Skip to content

Instantly share code, notes, and snippets.

@bear454
Created April 20, 2011 18:33
Show Gist options
  • Save bear454/932248 to your computer and use it in GitHub Desktop.
Save bear454/932248 to your computer and use it in GitHub Desktop.
Filter a set of attributes on a collection to only show the varying attributes
#! /usr/bin/ruby
# data set:
# id | name | score | postal | color
# 1 | john | 14 | 12345 | blue
# 2 | jane | 10 | 12345 | blue
# 3 | jeff | 6 | 12345 | green
# define a simple class for holding the dataset
class Thing
attr_reader :id, :name, :score, :postal, :color
#quick & dirty setup
def initialize(id, name, score, postal, color)
@id = id
@name = name
@score = score
@postal = postal
@color = color
end
#something that looks more like ActiveRecord
def attribute_names
[:id, :name, :score, :postal, :color]
end
def attributes
{ :id => @id,
:name => @name,
:score => @score,
:postal => @postal,
:color => @color
}
end
end
# the meat
def diff_collection(collection, key, always_include = [], ignore = [])
# find some more attributes to ignore
(collection.first.attribute_names - always_include - ignore).each do |attribute|
attribute_set = collection.collect(&attribute)
ignore << attribute if attribute_set.all?{|n| n == attribute_set[0]}
end
#set the attributes in order, always_include's first, then the rest of the comparables
comparable_attributes = (always_include + (collection.first.attribute_names - always_include - ignore))
#build the output set
results = {}
collection.each do |instance|
# collect the relevant attributes as 2-dimensional array to maintain order
attributes = comparable_attributes.collect{|attribute| [attribute, instance.send(attribute)] }
#add to the result set using the key attribute
results[instance.send(key)] = attributes
end
results
end
#construct the collection
things = [ Thing.new(1, 'john', 14, '12345', 'blue'),
Thing.new(2, 'jane', 10, '12345', 'blue'),
Thing.new(3, 'jeff', 6, '12345', 'green') ]
# do it already!
results = diff_collection(things, :id, [:name], [:id])
#print out something nice
results.each do |key, attributes|
puts "[#{key}] #{attributes.collect{|a| "#{a[0]} => '#{a[1]}' "} }"
end
# output:
# [1] name => 'john' score => '14' color => 'blue'
# [2] name => 'jane' score => '10' color => 'blue'
# [3] name => 'jeff' score => '6' color => 'green'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment