Change a data structure

Hello!

I’ve got the following data structure, which I need to change, to
suit further needs:

timing_given = {
 “Performance Test of Item Access using Lists” => [
  {“Plants” => 100, “Customers” => 50, “Total” => 150},
  {“Plants” => 85,  “Customers” => 60, “Total” => 140},
  {“Plants” => 111, “Customers” => 77, “Total” => 188}
 ],
 “Performance Test of Item Access using Advance Item Search” => [
  {“Work List” => 17, “Total” => 42},
{“Work List” => 10, “Total” => 50},
  {“Work List” => 22, “Total” => 99},
{“Work List” => 15, “Total” => 60}
 ]
}

Now I’d like to change that, so that it looks somewhat like this:

timing_wanted = {
 “Performance Test of Item Access using Lists” => {
  “Plants” => [100, 85, 111], “Customers” => [50, 60, 77], “Total” =>
[150, 140, 188]
 },
 Performance Test of Item Access using Advance Item Search" => {
  “Work List” => [17, 10, 22], “Bookmarks” => [30, 33, 27], “Total” =>
[42, 50, 99]
 }
}

Let me explain…

I’ve got a hash called “timing_given”, which has, right now, two keys.
These keys have arrays as values. The elements of these arrays are again
hashes.

Now this should be changed to match what’s shown in “timing_wanted”.
Ie.,
create a hash, which has two keys. These keys should have hashes as
values
and the values of these hashes should be arrays.

The data represent some timing measurement data. In the example I’m
showing,
the Plants, Customers and Total tests have been run 3 times,
consecutively.
So, first the Plants test was run, then the Customers test and then the
Total test.

I want to collect all the Plants (etc.pp.) tests in one array. This
array
should have as many elements, as there were test runs for the Plants
test.
Accordingly for the other tests.

In reality, there are more tests than what I’ve shown. And as you can
see,
there are two test “categories”, called “Performance Test of Item Access
using Lists” and “Performance Test of Item Access using Advance Item
Search”.
In reality, there might be more. Under these categories, there might be
2, 3, 4 or whatever test runs - but the number of test runs for a
category
is always constant.

How would I best “mess up” that timing_given data structure, so that it
resembles the timing_wanted structure?

Thanks a lot,
Michael

Michael S. wrote:

Hello!

I’ve got the following data structure, which I need to change, to
suit further needs:

timing_given = {
 “Performance Test of Item Access using Lists” => [
  {“Plants” => 100, “Customers” => 50, “Total” => 150},
  {“Plants” => 85,  “Customers” => 60, “Total” => 140},
  {“Plants” => 111, “Customers” => 77, “Total” => 188}
 ],
 “Performance Test of Item Access using Advance Item Search” => [
  {“Work List” => 17, “Total” => 42},
{“Work List” => 10, “Total” => 50},
  {“Work List” => 22, “Total” => 99},
{“Work List” => 15, “Total” => 60}
 ]
}

Now I’d like to change that, so that it looks somewhat like this:

timing_wanted = {
 “Performance Test of Item Access using Lists” => {
  “Plants” => [100, 85, 111], “Customers” => [50, 60, 77], “Total” =>
[150, 140, 188]
 },
 Performance Test of Item Access using Advance Item Search" => {
  “Work List” => [17, 10, 22], “Bookmarks” => [30, 33, 27], “Total” =>
[42, 50, 99]
 }
}

Let me explain…

I’ve got a hash called “timing_given”, which has, right now, two keys.
These keys have arrays as values. The elements of these arrays are again
hashes.

Now this should be changed to match what’s shown in “timing_wanted”.
Ie.,
create a hash, which has two keys. These keys should have hashes as
values
and the values of these hashes should be arrays.

The data represent some timing measurement data. In the example I’m
showing,
the Plants, Customers and Total tests have been run 3 times,
consecutively.
So, first the Plants test was run, then the Customers test and then the
Total test.

I want to collect all the Plants (etc.pp.) tests in one array. This
array
should have as many elements, as there were test runs for the Plants
test.
Accordingly for the other tests.

In reality, there are more tests than what I’ve shown. And as you can
see,
there are two test “categories”, called “Performance Test of Item Access
using Lists” and “Performance Test of Item Access using Advance Item
Search”.
In reality, there might be more. Under these categories, there might be
2, 3, 4 or whatever test runs - but the number of test runs for a
category
is always constant.

How would I best “mess up” that timing_given data structure, so that it
resembles the timing_wanted structure?

Thanks a lot,
Michael

Try this:

timing_given = {
“Performance Test of Item Access using Lists” => [
{“Plants” => 100, “Customers” => 50, “Total” => 150},
{“Plants” => 85, “Customers” => 60, “Total” => 140},
{“Plants” => 111, “Customers” => 77, “Total” => 188}
],
“Performance Test of Item Access using Advance Item Search” => [
{“Work List” => 17, “Total” => 42},
{“Work List” => 10, “Total” => 50},
{“Work List” => 22, “Total” => 99},
{“Work List” => 15, “Total” => 60}
]
}

timing_wanted = {}

timing_given.each do |key1, value1|
#Make a list be the default lookup value
#for a non-existent hash key:

timing_wanted[key1] = Hash.new do |h, k|
h[k] = []
end

value1.each do |hash|
hash.each do |key2, value2|
timing_wanted[key1][key2] << hash[key2]
end
end
end

p timing_wanted

–output:–
{“Performance Test of Item Access using Advance Item Search”=>{“Work
List”=>[17, 10, 22, 15], “Total”=>[42, 50, 99, 60]}, “Performance Test
of Item Access using Lists”=>{“Plants”=>[100, 85, 111], “Total”=>[150,
140, 188], “Customers”=>[50, 60, 77]}}

On Jan 24, 2:14 am, Michael S. [email protected] wrote:

],

Let me explain…
the Plants, Customers and Total tests have been run 3 times, consecutively.
In reality, there might be more. Under these categories, there might be
2, 3, 4 or whatever test runs - but the number of test runs for a category
is always constant.

How would I best “mess up” that timing_given data structure, so that it
resembles the timing_wanted structure?

Thanks a lot,
Michael

I’ll offer up an inject version (mostly for novelty’s sake):
timing_given.each {|k, v| timing_given[k] = v.inject(Hash.new {|h, k|
h[k] = []}) {|acc, h| h.each {|k, v| acc[k] << v}; acc}}

7stud – [email protected] wrote:

Try this:

Your code works great - but I changed the data structure in the
meantime, as an Array suits my needs better :frowning: Please see
news:[email protected].

Thanks,
Michael

On Jan 24, 9:06 am, Michael S. [email protected] wrote:

yermej [email protected] wrote:

I’ll offer up an inject version (mostly for novelty’s sake):
timing_given.each {|k, v| timing_given[k] = v.inject(Hash.new {|h, k|
h[k] = []}) {|acc, h| h.each {|k, v| acc[k] << v}; acc}}

Geez - did you use to code perl code? Because Perl code tends to
be as unreadable and compact as yours :slight_smile:

Yes, I’ve used Perl in the past, but my penchant for inject is rooted
in Scheme.

It works good, but I guess I’ve got some reading to do, to actually
understand why it’s working ;->

This might help, though some would say it’s better just to avoid
inject entirely:

timing_given.each do |test_type, test_data|
timing_given[test_type] =
test_data.inject(Hash.new {|h, k| h[k] = []}) do |new_hash,
old_hash|
old_hash.each do |data_field, data_value|
new_hash[data_field] << data_value
end
new_hash
end
end

Michael S. wrote:

yermej [email protected] wrote:

I’ll offer up an inject version (mostly for novelty’s sake):
timing_given.each {|k, v| timing_given[k] = v.inject(Hash.new {|h, k|
h[k] = []}) {|acc, h| h.each {|k, v| acc[k] << v}; acc}}

Geez - did you use to code perl code? Because Perl code tends to
be as unreadable and compact as yours :slight_smile:

It works good, but I guess I’ve got some reading to do, to actually
understand why it’s working ;->

Don’t bother. inject() is such an inefficient function it should never
be used in ruby code.

yermej [email protected] wrote:

I’ll offer up an inject version (mostly for novelty’s sake):
timing_given.each {|k, v| timing_given[k] = v.inject(Hash.new {|h, k|
h[k] = []}) {|acc, h| h.each {|k, v| acc[k] << v}; acc}}

Geez - did you use to code perl code? Because Perl code tends to
be as unreadable and compact as yours :slight_smile:

It works good, but I guess I’ve got some reading to do, to actually
understand why it’s working ;->

Cheers,

Michael

On Jan 24, 2008, at 10:02 AM, 7stud – wrote:

It works good, but I guess I’ve got some reading to do, to actually
understand why it’s working ;->

Don’t bother. inject() is such an inefficient function it should
never
be used in ruby code.

Ouch. That’s a pretty bold claim.

Is inject() too inefficient for use on a ten element Array? How about
three?

Perhaps “never” was the wrong word.

James Edward G. II

On Fri, 25 Jan 2008 00:24:57 +0900, yermej wrote:

  new_hash
end

end

Why would this be preferable to using a db for storing data? I don’t
understand the prevalence of Hash.

-Thufir

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Jan 24, 2008, at 10:02 AM, 7stud – wrote:

It works good, but I guess I’ve got some reading to do, to actually
understand why it’s working ;->

Don’t bother. inject() is such an inefficient function it should
never
be used in ruby code.

No, it’s too slow only if you have profiled a specific application and
the profiling software pegs it as being the culprit. Premature
optimization and all that. If it’s only going over a small data set,
it probably doesn’t matter. If it does matter, then there’s
probably a bigger algorithm problem. In the meantime, it presents a
syntactic sugar for some people.

But if that code was sugar, I think there’s some vinegar in it …
inject probably isn’t the right answer in terms of maintainability in
this case. After all, yermej said it was for novelty’s sake. :slight_smile:

David M.
Maia Mailguard http://www.maiamailguard.com
[email protected]

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iD8DBQFHmOq1Uy30ODPkzl0RAiZYAKC+zC1rJxiWCqbAZHec0mRxMJivowCgimmH
+v2xp6hWUwXhRAnxfd6OzPw=
=cTQQ
-----END PGP SIGNATURE-----