Skip to content

Instantly share code, notes, and snippets.

@amiel
Forked from bear454/set-matching.rb
Created April 20, 2011 19:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amiel/932356 to your computer and use it in GitHub Desktop.
Save amiel/932356 to your computer and use it in GitHub Desktop.
#! /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
comparable_attributes = collection.first.attribute_names - ignore
comparable_attributes.each do |attribute|
attribute_set = collection.collect(&attribute)
comparable_attributes.delete(attribute) if attribute_set.uniq.size == 1
end
attributes = comparable_attributes | always_include
# build the output set
# each_with_object requires activesupport; you could easily use inject instead.
collection.each_with_object({}) do |instance, results|
# collect the relevant attributes as 2-dimensional array to maintain order
results[instance.send(key)] = attributes.collect{|attribute| [attribute, instance.send(attribute)] }
end
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