Manipulating an Array of Structs

A

Anthony Wright

I have data that I've extracted from a database, that I wish to pass to
a calling (external) piece of software through Drb.

The are a large number of data set formats, but an employee based
example might look something like:

ID Name Age
1 Mary Smith 23
3 Frank Zappa 52
19 Mary Jones 41

I'm trying to find a "nice" structure to pass this data around in, so
that it can be easily understood and manipulated.




I'm currently using an Array of Hashes so it looks something like:

[ { :id => 1, :name => "Mary Smith", :age => 23 }, { :id => 3, :name =>
"Frank Zappa", :age => 52 }, { :id =>19, :name => "Mary Jones", :age =>
41 } ]

or more nicely formatted

[
{ :id => 1, :name => "Mary Smith", :age => 23 },
{ :id => 3, :name => "Frank Zappa", :age => 52 },
{ :id =>19, :name => "Mary Jones", :age => 41 }
]



This is fine if I want to extract single pieces of information, but it's
clumsy to manipulate the whole array, for example, extract out all the
names, sort the array by age, create a new array containing employees
over 40. It's also inefficient as I'm repeating the labels on every record.

I realise I can do this by writing block code to process the array, but
I feel there must be a cleaner way to store and manipulate data of this
form in ruby. Something on the lines of Struct would be great to remove
the excessing labels, but Struct doesn't help with the array manipulation.


Suggestions would be really welcome, preferabling using standard
classes, but will look at extensions.

thanks,

Anthony Wright.
 
R

Robert Klemme

2010/4/7 Anthony Wright said:
I have data that I've extracted from a database, that I wish to pass to
a calling (external) piece of software through Drb.

The are a large number of data set formats, but an employee based
example might look something like:

ID =A0 =A0 Name =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Age
=A01 =A0 =A0 Mary Smith =A0 =A0 =A0 =A0 =A0 23
=A03 =A0 =A0 Frank Zappa =A0 =A0 =A0 =A0 =A052
19 =A0 =A0 Mary Jones =A0 =A0 =A0 =A0 =A0 41

I'm trying to find a "nice" structure to pass this data around in, so
that it can be easily understood and manipulated.

I'm currently using an Array of Hashes so it looks something like:
[
=A0 =A0 =A0 =A0{ :id =3D> 1, :name =3D> "Mary Smith", =A0:age =3D> 23 },
=A0 =A0 =A0 =A0{ :id =3D> 3, :name =3D> "Frank Zappa", :age =3D> 52 },
=A0 =A0 =A0 =A0{ :id =3D>19, :name =3D> "Mary Jones", =A0:age =3D> 41 }
]


This is fine if I want to extract single pieces of information, but it's
clumsy to manipulate the whole array, for example, extract out all the
names, sort the array by age, create a new array containing employees
over 40. It's also inefficient as I'm repeating the labels on every recor= d.

I realise I can do this by writing block code to process the array, but
I feel there must be a cleaner way to store and manipulate data of this
form in ruby. =A0Something on the lines of Struct would be great to remov= e
the excessing labels, but Struct doesn't help with the array manipulation=
 
J

Jesús Gabriel y Galán

2010/4/7 Anthony Wright said:
I have data that I've extracted from a database, that I wish to pass to
a calling (external) piece of software through Drb.

The are a large number of data set formats, but an employee based
example might look something like:

ID =A0 =A0 Name =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Age
=A01 =A0 =A0 Mary Smith =A0 =A0 =A0 =A0 =A0 23
=A03 =A0 =A0 Frank Zappa =A0 =A0 =A0 =A0 =A052
19 =A0 =A0 Mary Jones =A0 =A0 =A0 =A0 =A0 41

I'm trying to find a "nice" structure to pass this data around in, so
that it can be easily understood and manipulated.

I'm currently using an Array of Hashes so it looks something like:
[
=A0 =A0 =A0 =A0{ :id =3D> 1, :name =3D> "Mary Smith", =A0:age =3D> 23 },
=A0 =A0 =A0 =A0{ :id =3D> 3, :name =3D> "Frank Zappa", :age =3D> 52 },
=A0 =A0 =A0 =A0{ :id =3D>19, :name =3D> "Mary Jones", =A0:age =3D> 41 }
]


This is fine if I want to extract single pieces of information, but it's
clumsy to manipulate the whole array, for example, extract out all the
names, sort the array by age, create a new array containing employees
over 40. It's also inefficient as I'm repeating the labels on every reco= rd.

I realise I can do this by writing block code to process the array, but
I feel there must be a cleaner way to store and manipulate data of this
form in ruby. =A0Something on the lines of Struct would be great to remo= ve
the excessing labels, but Struct doesn't help with the array manipulatio=
n.

I don't see your issue with the "array manipulation". =A0Fact is, that
if you have a collection of items you have to either iterate through
all to process and filter them or you need to create indexes which you
need to keep in sync with the base data (much the same way a RDBMS
does btw.).

We have Enumerable#map, #select, #reject and a few more methods which
work pretty well. =A0If you use Struct or OpenStruct you can even use
map like this:

all_names =3D employees.map(&:name)

If find that succinct enough. =A0And even with Hashes you get

all_names =3D employees.map {|emp| emp[:name]}

This is a bit more verbose but still not too way off I'd say. =A0My 0.02E=
UR.

If you want to spare the client of that data to be performing the same
kind of work, you can build a class that provides those methods. For
example:

Employee =3D Struct.new:)id, :name, :age)

class EmployeeSet
def initialize
@employee_list =3D []
end
def add emp
@employee_list << emp
end

def all_names
@employee_list.map {|e| e.name}
end
# and so on for all the method you would provide
end

list =3D EmployeeSet.new
list.add Employee.new(1, "Mary", 23)
#...
list.all_names


Jesus.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top