<commit_before>module DataTable
  class ResultGroup
    attr_accessor :group_object, :rows
    attr_accessor :level, :total_levels
    attr_accessor :sum

    def initialize(group_object, rows, total_levels = 0)
      @group_object = group_object.blank? ? nil : group_object.to_s
      @rows  = rows
      @level = 0
      @total_levels = total_levels
    end


    def level=(new_level)
      @level = new_level
      @rows.each do |row|
        if row.is_a? ResultGroup
          row.total_levels = @total_levels
          row.level = new_level + 1
        end
      end
    end


    def count
      @rows.map { |r| r.is_a?(self.class) ? r.count : 1 }.sum
    end


    def group(groups)
      groups = [groups] unless groups.is_a?(Array)

      return if groups.empty?
      new_rows = []

      first_group = groups.shift
      new_group = if @rows.first.is_a? ResultGroup
        @rows.map{|rg| [rg.group_object, rg.group_children(first_group)]}
      else
        if first_group == true
          {'All' => @rows}
        elsif first_group.is_a?(Hash)
          @rows.group_by{|r|
            r.send(first_group.keys.first).send(first_group.values.first)
          }
        else
          @rows.group_by{|r| r.send(first_group)}
        end
      end
      @total_levels += 1
      new_group.each do |group, rows|
        r = ResultGroup.new(group, rows, @total_levels)
        r.level = @level + 1
        new_rows << r
      end

      @rows = new_rows
      group(groups) unless groups.empty?
      @rows
    end


    def group_children(group)
      if @rows.first.is_a?(ResultGroup)
        @rows.each{|r| r.group_children(group)}
        @rows
      else
        self.group(group)
      end
    end


    def aggregate(fields)
      @sum ||= {}

      fields.each do |field, aggregation|
        @sum[field] = nil

        @rows.each do |row|<commit_msg>Allow ordering of groups by string of group name or by row count<commit_after>module DataTable
  class ResultGroup
    attr_accessor :group_object, :rows
    attr_accessor :level, :total_levels
    attr_accessor :sum

    def initialize(group_object, rows, total_levels = 0)
      @group_object = group_object.blank? ? nil : group_object.to_s
      @rows  = rows
      @level = 0
      @total_levels = total_levels
    end


    def level=(new_level)
      @level = new_level
      @rows.each do |row|
        if row.is_a? ResultGroup
          row.total_levels = @total_levels
          row.level = new_level + 1
        end
      end
    end


    def count
      @rows.map { |r| r.is_a?(self.class) ? r.count : 1 }.sum
    end


    def group(groups, order = nil)
      groups = [groups] unless groups.is_a?(Array)

      return if groups.empty?
      new_rows = []

      first_group = groups.shift
      new_group = if @rows.first.is_a? ResultGroup
        @rows.map{|rg| [rg.group_object, rg.group_children(first_group, order)]}
      else
        if first_group == true
          {'All' => @rows}
        elsif first_group.is_a?(Hash)
          @rows.group_by{|r|
            r.send(first_group.keys.first).send(first_group.values.first)
          }
        else
          @rows.group_by{|r| r.send(first_group)}
        end
      end

      new_group = case order.try(:to_sym)
      when :group_name
        Hash[new_group.sort { |a,b| a.first.to_s <=> b.first.to_s }]
      when :row_count
        Hash[new_group.sort { |a,b| b.last.size <=> a.last.size }]
      else
        new_group
      end

      @total_levels += 1
      new_group.each do |group, rows|
        r = ResultGroup.new(group, rows, @total_levels)
        r.level = @level + 1
        new_rows << r
      end

      @rows = new_rows
      group(groups, order) unless groups.empty?
      @rows
    end


    def group_children(group, order = nil)
      if @rows.first.is_a?(ResultGroup)
        @rows.each{|r| r.group_children(group, order)}
        @rows
      else
        self.group(group, order)
      end
    end


    def aggregate(fields)
      @sum ||= {}

      fields.each do |field, aggregation|
        @sum[field] = nil

        @rows.each do |row|
{'fraction_non_alphanumeric': 0.10840438489646773, 'fraction_numerical': 0.00292326431181486, 'mean_word_length': 1.9948942377826404, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4986702', 'n_tokens_mistral': 1415, 'n_tokens_neox': 1347, 'n_words': 307}