Sha256: d1f057389dd9a08a882495cd96401bceed4a39a07f6af447f9979d0aa3b2b97a

Contents?: true

Size: 1.84 KB

Versions: 5

Compression:

Stored size: 1.84 KB

Contents

# frozen_string_literal: true

require_relative '../../helpers/transform_to_sortable_numeric'
require_relative '../enumerable_set_instruction'

class ActiveSet
  module Sorting
    class EnumerableStrategy
      def initialize(set, attribute_instructions)
        @set = set
        @attribute_instructions = attribute_instructions
        @set_instructions = attribute_instructions.map do |attribute_instruction|
          EnumerableSetInstruction.new(attribute_instruction, set)
        end
      end

      def execute
        # http://brandon.dimcheff.com/2009/11/18/rubys-sort-vs-sort-by/
        @set.sort_by do |item|
          @set_instructions.map do |set_instruction|
            value_for_comparison = sortable_numeric_for(set_instruction, item)
            direction_multiplier = direction_multiplier(set_instruction.value)

            # When ActiveSet.configuration.on_asc_sort_nils_come == :last
            # null values to be sorted as if larger than any non-null value.
            # ASC => [-2, -1, 1, 2, nil]
            # DESC => [nil, 2, 1, -1, -2]
            # Otherwise sort nulls as if smaller than any non-null value.
            # ASC => [nil, -2, -1, 1, 2]
            # DESC => [2, 1, -1, -2, nil]
            if value_for_comparison.nil?
              [direction_multiplier * nil_sorter, 0]
            else
              [0, value_for_comparison * direction_multiplier]
            end
          end
        end
      end

      def sortable_numeric_for(set_instruction, item)
        value = set_instruction.attribute_value_for(item)

        transform_to_sortable_numeric(value)
      end

      def direction_multiplier(direction)
        return -1 if direction.to_s.downcase.start_with? 'desc'

        1
      end

      def nil_sorter
        return 1 if ActiveSet.configuration.on_asc_sort_nils_come == :last

        -1
      end
    end
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
actionset-0.11.0 lib/active_set/sorting/enumerable_strategy.rb
actionset-0.10.0 lib/active_set/sorting/enumerable_strategy.rb
actionset-0.9.2 lib/active_set/sorting/enumerable_strategy.rb
actionset-0.9.1 lib/active_set/sorting/enumerable_strategy.rb
actionset-0.8.2 lib/active_set/sorting/enumerable_strategy.rb