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 Schmarck 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]}}

···

--
Posted via http://www.ruby-forum.com/\.

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}}

···

On Jan 24, 2:14 am, Michael Schmarck <michael.schma...@here.la> 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

Your code works great - but I changed the data structure in the
meantime, as an Array suits my needs better :frowning: Please see
<news:1441063.yT1qbWcgPr@michael-schmarck.my-fqdn.de>.

Thanks,
Michael

···

7stud -- <bbxx789_05ss@yahoo.com> wrote:

Try this:

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

···

yermej <yermej@gmail.com> 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}}

> 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

···

On Jan 24, 9:06 am, Michael Schmarck <michael.schma...@here.la> wrote:

yermej <yer...@gmail.com> wrote:

Michael Schmarck wrote:

···

yermej <yermej@gmail.com> 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.
--
Posted via http://www.ruby-forum.com/\.

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 Gray II

···

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

Michael Schmarck wrote:

yermej <yermej@gmail.com> 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.

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 Morton
Maia Mailguard http://www.maiamailguard.com
mortonda@dgrmm.net

···

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

Michael Schmarck wrote:

yermej <yermej@gmail.com> 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.

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

-Thufir

···

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

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