I've run into a number of situations where I need to group an array
while preserving order. For example, grouping the results of a database
query without affecting their order or introducing extraneous logic in a
view.
I would like to know if there are any obvious problems or improvements
to this solution:
class Array
def partition_by(&b)
out=[]
self.inject([]) {|acc,e|
last = acc.pop
value = b.call(e)
out << {value=>[]} if last != value
out.last[value] << e
acc << value
}
out
end
end
So if I partition an array by element length, for example (contrived, I
know):
animals = %w(dog dog cat chicken chicken dog)
animals.partition_by{|x| x.length}
I get:
[{3=>["dog", "dog", "cat"]}, {7=>["chicken", "chicken"]}, {3=>["dog"]}]
class Array
def group_by
key = nil
inject(){|result,x|
k = yield x
if key == k and result !=
result[-1] << x
next result
end
key = k
result <<
}
end
end
···
On Sep 20, 4:47 pm, Matt Constantine <desig...@gmail.com> wrote:
Hi all,
I've run into a number of situations where I need to group an array
while preserving order. For example, grouping the results of a database
query without affecting their order or introducing extraneous logic in a
view.
I would like to know if there are any obvious problems or improvements
to this solution:
class Array
def partition_by(&b)
out=
self.inject() {|acc,e|
last = acc.pop
value = b.call(e)
out << {value=>} if last != value
out.last[value] << e
acc << value
}
out
end
end
So if I partition an array by element length, for example (contrived, I
know):
animals = %w(dog dog cat chicken chicken dog)
animals.partition_by{|x| x.length}
I get:
[{3=>["dog", "dog", "cat"]}, {7=>["chicken", "chicken"]}, {3=>["dog"]}]
module Enumerable
def group_by_ordered
inject() do |agg, v|
k = yield v
if agg.empty? || k != agg.last.first
agg << [k, [v]]
else
agg.last.last << v
end
agg
end
end
end
On Sep 20, 4:47 pm, Matt Constantine <desig...@gmail.com> wrote:
Hi all,
I've run into a number of situations where I need to group an array
while preserving order. For example, grouping the results of a database
query without affecting their order or introducing extraneous logic in a
view.
I would like to know if there are any obvious problems or improvements
to this solution:
class Array
def partition_by(&b)
out=
self.inject() {|acc,e|
last = acc.pop
value = b.call(e)
out << {value=>} if last != value
out.last[value] << e
acc << value
}
out
end
end
So if I partition an array by element length, for example (contrived, I
know):
animals = %w(dog dog cat chicken chicken dog)
animals.partition_by{|x| x.length}
I get:
[{3=>["dog", "dog", "cat"]}, {7=>["chicken", "chicken"]}, {3=>["dog"]}]
Without hashes:
class Array
def group_by
key = nil
inject(){|result,x|
k = yield x
if key == k and result !=
result[-1] << x
next result
end
key = k
result <<
}
end
end