class TransformableList
Constants
- VERSION
Public Class Methods
new(items, matcher: -> a, b { a == b }
click to toggle source
# File lib/transformable_list.rb, line 5 def initialize(items, matcher: -> a, b { a == b }) @items = items @matcher = matcher end
Public Instance Methods
transform(new_items)
click to toggle source
# File lib/transformable_list.rb, line 10 def transform(new_items) build_remaining_items_index! moves = [] creates = [] deletes = [] indexes_to_keep = Set.new new_items.map.with_index do |new_item, new_index| if existing_index = find_index_and_eliminate_match(new_item) if new_index != existing_index moves << [:move, @items[existing_index], new_index] end indexes_to_keep << existing_index else creates << [:create, new_item, new_index] end end (0...@items.size).each do |index| unless indexes_to_keep.include?(index) deletes << [:delete, @items[index], index] end end deletes.sort_by(&:last) + creates.sort_by(&:last) + moves.sort_by(&:last) end
Private Instance Methods
build_remaining_items_index!()
click to toggle source
# File lib/transformable_list.rb, line 42 def build_remaining_items_index! @remaining_items = @items.map.with_index{|item, i| [item, i]} end
find_index_and_eliminate_match(new_item)
click to toggle source
# File lib/transformable_list.rb, line 46 def find_index_and_eliminate_match(new_item) remaining_index = @remaining_items.index{|item, _| item.object_id == new_item.object_id} || @remaining_items.index{|item, _| match?(item, new_item)} _, original_index = if remaining_index result = @remaining_items[remaining_index] @remaining_items.delete_at(remaining_index) result end original_index end
match?(a, b)
click to toggle source
# File lib/transformable_list.rb, line 60 def match?(a, b) @matcher.(a, b) end