Skip to content

Instantly share code, notes, and snippets.

@tuxagon
Created March 31, 2018 20:51
Show Gist options
  • Select an option

  • Save tuxagon/db77aba8fdf324c276798972cd5767a0 to your computer and use it in GitHub Desktop.

Select an option

Save tuxagon/db77aba8fdf324c276798972cd5767a0 to your computer and use it in GitHub Desktop.
A list zipper implemented in ruby
class ListZipper
attr_reader :left
attr_reader :focus
attr_reader :right
def initialize(list)
list = ensure_array(list)
@focus = list.first
@left = []
@right = list.drop(1)
end
def move_back(n=1)
return self if invalid_movement?(n, @left)
n = normalize_movement(n, @left)
@right.unshift(@focus)
(1..n).each do |x|
@right.unshift(@left.pop)
end
@focus = @right.shift
self
end
def move_forward(n=1)
return self if invalid_movement?(n, @right)
n = normalize_movement(n, @right)
@left.push(@focus)
(1..n).each do |x|
@left.push(@right.shift)
end
@focus = @left.pop
self
end
private
def ensure_array(object)
return [] if object.nil?
return object if object.respond_to?(:to_ary)
[object]
end
def invalid_movement?(n, list)
n < 1 || list.empty?
end
def normalize_movement(n, list)
if n > list.length
list.length
else
n
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment