# Ruby one-liner needed

**URL:** <https://www.ruby-forum.com/t/ruby-one-liner-needed/56349>\
**Category:** Ruby\
**Created:** [December 2, 2005, 10:01am UTC](https://www.ruby-forum.com/t/ruby-one-liner-needed/56349 "2005-12-02T10:01:12Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![kevin.jackson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/85f322/32.png) [@kevin.jackson](https://www.ruby-forum.com/u/kevin.jackson)\
**Post date:** [December 2, 2005, 10:01am UTC](https://www.ruby-forum.com/t/ruby-one-liner-needed/56349/1 "2005-12-02T10:01:12Z")

</div>

Here’s one taht I know is possible (I’m sure I’ve seen it somewhere  
before)

I have 2 arrays and I’d like to change them into a Hash  
stuff = [“1”, “2”, “3”]  
Item.column\_names.each { |column\_name| new\_item[column\_name] = stuff[?]  
}

The problem is how to index within the block to move along the stuff  
array, and how to deal with the fact that most of the time the stuff  
array is shorter than the column\_names array

I’m sure using collect, map of something else ruby-ish that this is more  
than possible, but I can’t find a solution right now

Kev

---

<div class="post-metadata">

**Author:** ![kevin.jackson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/85f322/32.png) [@kevin.jackson](https://www.ruby-forum.com/u/kevin.jackson)\
**Post date:** [December 2, 2005, 10:17am UTC](https://www.ruby-forum.com/t/ruby-one-liner-needed/56349/2 "2005-12-02T10:17:26Z")

</div>

On 12/2/05, Kev J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I have 2 arrays and I’d like to change them into a Hash

pairs=%w(a b c d).zip(%w(x y));Hash[\*pairs.flatten]  
=\> {“a”=\>“x”, “b”=\>“y”, “c”=\>nil, “d”=\>nil}

---

<div class="post-metadata">

**Author:** ![kevin.jackson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/85f322/32.png) [@kevin.jackson](https://www.ruby-forum.com/u/kevin.jackson)\
**Post date:** [December 2, 2005, 10:21am UTC](https://www.ruby-forum.com/t/ruby-one-liner-needed/56349/3 "2005-12-02T10:21:32Z")

</div>

I’m sure there are many ways to do it, here’s one:

a=[3,4,5,6]  
b=%w{three four five six seven}  
res={}  
a.length.times {|i| break if i\>=b.length; res[a[i]]=b[i]; }

It handles the situation where either array is shorter than the other.

jf

---

<div class="post-metadata">

**Author:** ![kevin.jackson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/85f322/32.png) [@kevin.jackson](https://www.ruby-forum.com/u/kevin.jackson)\
**Post date:** [December 2, 2005, 10:41am UTC](https://www.ruby-forum.com/t/ruby-one-liner-needed/56349/4 "2005-12-02T10:41:50Z")

</div>

Johannes F. wrote:

> 

I’m using…

new\_item = Hash.new  
Item.column\_names.each { |column\_name| new\_item[column\_name] = row.shift  
}

at the moment and it’s working, so I won’t replace it with these  
suggestions

zip was the method I knew about but couldn’t remember 🙂

Kev

---

<div class="post-metadata">

**Author:** ![kevin.jackson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/85f322/32.png) [@kevin.jackson](https://www.ruby-forum.com/u/kevin.jackson)\
**Post date:** [December 2, 2005, 11:06am UTC](https://www.ruby-forum.com/t/ruby-one-liner-needed/56349/5 "2005-12-02T11:06:11Z")

</div>

Kev J. wrote:

> Here’s one taht I know is possible (I’m sure I’ve seen it somewhere before)
> 
> I have 2 arrays and I’d like to change them into a Hash  
> stuff = [“1”, “2”, “3”]  
> Item.column\_names.each { |column\_name| new\_item[column\_name] = stuff[?] }
> 
> The problem is how to index within the block to move along the stuff  
> array, and how to deal with the fact that most of the time the stuff  
> array is shorter than the column\_names array

stuff = [“1”, “2”, “3”]  
Item.column\_names.each\_with\_index { |column\_name, i|  
new\_item[column\_name] = stuff[i] }

---

<div class="post-metadata">

**Author:** ![kevin.jackson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/85f322/32.png) [@kevin.jackson](https://www.ruby-forum.com/u/kevin.jackson)\
**Post date:** [December 2, 2005, 11:26am UTC](https://www.ruby-forum.com/t/ruby-one-liner-needed/56349/6 "2005-12-02T11:26:37Z")

</div>

On Fri, 02 Dec 2005 09:00:30 -0000, Kev J.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’m sure using collect, map of something else ruby-ish that this is more  
> than possible, but I can’t find a solution right now
> 
> Kev

Well, theres lots of ways, but one is to inject the Hash as someone here  
showed me yesterday:

```
items.column_names.inject({}) { |hash, column_name| hash[column_name] =

```

row.shift ; hash }

(I wanted to eliminate the ‘; hash’ at the end of the closure but  
couldn’t  
find a way yet…)

However, I personally prefer Simon’s solution, which can be a real  
one-liner too 🙂

```
Hash[*items.column_names.zip(row).flatten]

```

---

<div class="post-metadata">

**Author:** ![kevin.jackson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/85f322/32.png) [@kevin.jackson](https://www.ruby-forum.com/u/kevin.jackson)\
**Post date:** [December 2, 2005, 5:08pm UTC](https://www.ruby-forum.com/t/ruby-one-liner-needed/56349/7 "2005-12-02T17:08:43Z")

</div>

Hi –

On Fri, 2 Dec 2005, David A. Black wrote:

> > The problem is how to index within the block to move along the stuff array,  
> > and how to deal with the fact that most of the time the stuff array is  
> > shorter than the column\_names array
> > 
> > I’m sure using collect, map of something else ruby-ish that this is more  
> > than possible, but I can’t find a solution right now
> 
> a = [1,2,3]  
> b = [4,5,6,7,8]  
> Hash[\*a.zip(b[0,a.size]).flatten  
> =\> {1=\>4, 2=\>5, 3=\>6}

Actually just use the shorter one first and zip won’t fill it out with  
nils:

Hash[\*a.zip(b).flatten]

David

–  
David A. Black  
removed\_email\_address@domain.invalid

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!

---

<div class="post-metadata">

**Author:** ![kevin.jackson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/85f322/32.png) [@kevin.jackson](https://www.ruby-forum.com/u/kevin.jackson)\
**Post date:** [December 2, 2005, 3:39pm UTC](https://www.ruby-forum.com/t/ruby-one-liner-needed/56349/8 "2005-12-02T15:39:16Z")

</div>

Hi –

On Fri, 2 Dec 2005, Kev J. wrote:

> I’m sure using collect, map of something else ruby-ish that this is more than  
> possible, but I can’t find a solution right now

a = [1,2,3]  
b = [4,5,6,7,8]  
Hash[\*a.zip(b[0,a.size]).flatten  
=\> {1=\>4, 2=\>5, 3=\>6}

The problem with flatten is that it can be overzealous, but it looks  
like you probably don’t have nested arrays. If you do, you can get  
the flattenx package from RAA and use flatten\_once.

David

–  
David A. Black  
removed\_email\_address@domain.invalid

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!

---

<div class="post-metadata">

**Author:** ![kevin.jackson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/85f322/32.png) [@kevin.jackson](https://www.ruby-forum.com/u/kevin.jackson)\
**Post date:** [December 2, 2005, 5:12pm UTC](https://www.ruby-forum.com/t/ruby-one-liner-needed/56349/9 "2005-12-02T17:12:48Z")

</div>

Hi –

On Sat, 3 Dec 2005, David A. Black wrote:

> > > 
> > 
> > a = [1,2,3]  
> > b = [4,5,6,7,8]  
> > Hash[\*a.zip(b[0,a.size]).flatten  
> > =\> {1=\>4, 2=\>5, 3=\>6}
> 
> Actually just use the shorter one first and zip won’t fill it out with  
> nils:
> 
> Hash[\*a.zip(b).flatten]

I hereby swear I will stop posting until I am being torn in no more  
than ten directions at the same time 🙂 In other words: I realize  
that you can’t just switch them around at will. So you have to decide  
whether you’re happy to have nils or if you want to truncate the hash  
based on available values.

So adapt as needed 🙂

David

P.S. One of the things I’ve been grappling with today is (the third  
day of) intermittent/non-existent Internet service – and a mysterious  
reboot on my server. So I got and read this thread out of order.  
Sorry if I reinvented anyone’s wheel 🙂

–  
David A. Black  
removed\_email\_address@domain.invalid

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!
