Array to Hash

is it possible to convert easily an Array like this one :

[ nil, “b”, nil, nil, nil , “f”, “g”, nil, nil, “j”]

to an Hash like this one

{ 1 => “b”, 5 => “f”, 6 => “g”, 9 => “j” }

where the key is the position of a value if not nil … ?

In message [email protected], Josselin writes:

is it possible to convert easily an Array like this one :

[ nil, “b”, nil, nil, nil , “f”, “g”, nil, nil, “j”]

to an Hash like this one

{ 1 => “b”, 5 => “f”, 6 => “g”, 9 => “j” }

where the key is the position of a value if not nil … ?

Yes.

-s

array = [ nil, “b”, nil, nil, nil , “f”, “g”, nil, nil, “j”]
hash = {}
array.each_with_index { |value, index| hash[index] = value unless !
value }
puts hash.inspect

{5=>“f”, 6=>“g”, 1=>“b”, 9=>“j”}

-Chris-

Automation Engineer
Rally Software Development
ph: 303-565-2857

In message [email protected], Chris
Browne writes:

array = [ nil, “b”, nil, nil, nil , “f”, “g”, nil, nil, “j”]
hash = {}
array.each_with_index { |value, index| hash[index] = value unless ! value }
puts hash.inspect

My code was very similar to this.

5 quatloos to the first person to find a hypothetical case where this
code
produces the wrong answer.

-s

On May 3, 10:17 am, [email protected] (Peter S.) wrote:

produces the wrong answer.
When values are false. Replace condition from “! value” to
“value.nil?”.

On May 3, 10:41 am, [email protected] wrote:

When values are false. Replace condition from “! value” to
“value.nil?”.

Spoke too soon… also when duplicate array items exist…

Duplicate array items shouldn’t matter b/c your key value is the index
and not the value no?

On May 3, 10:51 am, “Doan, Alex” [email protected] wrote:

Duplicate array items shouldn’t matter b/c your key value is the index
and not the value no?

You’re right… I had it mixed up. Which begs to question (to the
original poster), what is the motivation for converting to hash? Out
of curiousity…

Good call, had value == nil in there but changed it right before I
replied.

-Chris-

Automation Engineer
Rally Software Development
ph: 303-565-2857

On 5/3/07, [email protected] [email protected] wrote:

5 quatloos to the first person to find a hypothetical case where this code
produces the wrong answer.

When values are false. Replace condition from “! value” to
“value.nil?”.

Not necessarily the simplest thing that could possibly work.

If you’re only interested in the hash being ‘equivalent’ to the array,
a simpler approach works:

array.each_with_index { |value, index| hash[index] = value }

Sure the array will have entries with keys mapping to nil values, but
you can’t tell the difference with [] alone. If you want other
aspects of the hash then yes, go ahead and supress nil values


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

IPMS/USA Region 12 Coordinator
http://ipmsr12.denhaven2.com/

Visit the Project Mercury Wiki Site
http://www.mercuryspacecraft.com/

In message [email protected], Peter S.
writes:

In message [email protected], Josselin writes:

is it possible to convert easily an Array like this one :
[ nil, “b”, nil, nil, nil , “f”, “g”, nil, nil, “j”]
to an Hash like this one
{ 1 => “b”, 5 => “f”, 6 => “g”, 9 => “j” }
where the key is the position of a value if not nil … ?

Yes.

I thought about this more. I’d like to explain WHY there’s no code
in the above:

Because this is not just easy, but bloody obvious. What do you want
to do? You want to, for each index in the array, record its value
in a hash if it has a value. (Congrats! You’ve just reinvented sparse
arrays! Please put your hand in the cookie jar to see whether there’s
a cookie.)

So, what do you need? You need to do something for each index in the
array. If ONLY the Array class provided an each_index method… Oh, but
it does.

So, given an index, can you imagine a way to write code to extract the
member of an array at that index? You’d need some kind of operator to
extract a member of an array. And a way to check whether a value is
nil.
All of these are not merely available, but easy. Even if you don’t
know that there’s an each_index method, it’s not hard to maintain a
count
and do ‘count = count + 1; b[count] = x’ or something similar.

I guess this strikes me as a question that would have benefitted a lot
from
some explanation of why you weren’t just looking at the Array
documentation
and trying a few things.

-s

On 5/3/07, Rick DeNatale [email protected] wrote:

Sure the array will have entries with keys mapping to nil values,
.sub(“array”,“hash”)


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On 5/3/07, William J. [email protected] wrote:

where the key is the position of a value if not nil … ?

We don’t need no stinkin’ loops!

a=[ nil, “b”, nil, nil, nil , “f”, “g”, nil, nil, “j”]
=> [nil, “b”, nil, nil, nil, “f”, “g”, nil, nil, “j”]
h=Hash[*(0…a.size).zip(a).reject{|x|x[1]==nil}.flatten]
=> {5=>“f”, 6=>“g”, 1=>“b”, 9=>“j”}

Indeed,
require ‘enumerator’
a.enum_with_index.reject { |v, k| v.nil? }.inject({}) { |h, (v,k)|
h.update(k => v) }

PS. my solution preserves nested arrays, etc. in the original dataset

On May 3, 11:41 am, Josselin [email protected] wrote:

is it possible to convert easily an Array like this one :

[ nil, “b”, nil, nil, nil , “f”, “g”, nil, nil, “j”]

to an Hash like this one

{ 1 => “b”, 5 => “f”, 6 => “g”, 9 => “j” }

where the key is the position of a value if not nil … ?

We don’t need no stinkin’ loops!

a=[ nil, “b”, nil, nil, nil , “f”, “g”, nil, nil, “j”]
=> [nil, “b”, nil, nil, nil, “f”, “g”, nil, nil, “j”]
h=Hash[*(0…a.size).zip(a).reject{|x|x[1]==nil}.flatten]
=> {5=>“f”, 6=>“g”, 1=>“b”, 9=>“j”}