# Array.invert

**URL:** <https://www.ruby-forum.com/t/array-invert/100192>\
**Category:** Ruby\
**Created:** [December 13, 2005, 3:43pm UTC](https://www.ruby-forum.com/t/array-invert/100192 "2005-12-13T15:43:43Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![christer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a5b964/32.png) [@christer](https://www.ruby-forum.com/u/christer)\
**Post date:** [December 13, 2005, 3:43pm UTC](https://www.ruby-forum.com/t/array-invert/100192/1 "2005-12-13T15:43:43Z")

</div>

I would like to see invert “rubyfied”.  
(Yes, I’m trying to get a grip of what this word means 🙂

class Array  
def invert  
res=[]  
for i in 0…self.size  
if self[i] != nil then  
for b in self[i]  
res[b] = [] if res[b].nil?  
res[b] \<\< i  
end  
end  
end  
res  
end  
end

require ‘test/unit’  
class TestArray \< Test::Unit::TestCase  
def test\_invert\_1  
a = [[1,3],[1,4,5]]  
b = [nil,[0,1],nil,[0],[1],[1]]  
assert\_equal b,a.invert  
assert\_equal a,b.invert  
end

def test\_invert\_2  
a = []  
a \<\< [3,9,13] # 0  
a \<\< [3,11,14] # 1  
a \<\< [3,14,15] # 2  
a \<\< [4,1,4] # 3  
a \<\< [4,8,9] # 4  
a \<\< [5,0,1] # 5  
a \<\< [6,6,7] # 6  
a \<\< [14,2,6] # 7  
a \<\< [10,5,8,12,15] # 8  
a \<\< [10,10,11,12,13] # 9  
a \<\< [11,0,3,7,10] # 10  
a \<\< [17,2,3,4,5] # 11

```
# behead...
c = a.map {|head, *tail| tail}

b = []
b << [5,10] # 0
b << [3,5] # 1
b << [7,11] # 2
b << [10,11]# 3
b << [3,11] # 4
b << [8,11] # 5
b << [6,7] # 6
b << [6,10] # 7
b << [4,8] # 8
b << [0,4] # 9
b << [9,10] # 10
b << [1,9] # 11
b << [8,9] # 12
b << [0,9] # 13
b << [1,2] # 14
b << [2,8] # 15

assert_equal b,c.invert
assert_equal c,b.invert

```

end  
end

Christer

---

<div class="post-metadata">

**Author:** ![christer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a5b964/32.png) [@christer](https://www.ruby-forum.com/u/christer)\
**Post date:** [December 13, 2005, 4:44pm UTC](https://www.ruby-forum.com/t/array-invert/100192/2 "2005-12-13T16:44:39Z")

</div>

Hi –

On Tue, 13 Dec 2005, Christer N. wrote:

> I would like to see invert “rubyfied”.  
> (Yes, I’m trying to get a grip of what this word means 🙂

Aren’t we all? But the trying is so much fun 🙂

Here’s a version that might be more idiomatic, and that passes all  
your tests:

class Array  
def invert  
res=[]  
each\_with\_index do |e,i|  
if e  
e.each do |f|  
(res[f] ||= []) \<\< i  
end  
end  
end  
res  
end  
end

David

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

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

---

<div class="post-metadata">

**Author:** ![christer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a5b964/32.png) [@christer](https://www.ruby-forum.com/u/christer)\
**Post date:** [December 13, 2005, 4:47pm UTC](https://www.ruby-forum.com/t/array-invert/100192/3 "2005-12-13T16:47:39Z")

</div>

Christer N. wrote:

> ```
> res[b] << i
> end
> end
> end
> res
> 
> ```
> 
> end  
> end

I suggest

class Array  
def invert  
result = []  
each\_with\_index do |ary, idx|  
next if ary.nil?  
ary.each {|val| (result[val] ||= []).push(idx)}  
end  
result  
end  
end

As a matter of taste, you may want to write the two middle  
lines in just one line as

```
   ary.each {|val| (result[val] ||= []).push(idx)} unless ary.nil?

```

HTH,

Michael

---

<div class="post-metadata">

**Author:** ![christer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a5b964/32.png) [@christer](https://www.ruby-forum.com/u/christer)\
**Post date:** [December 13, 2005, 5:11pm UTC](https://www.ruby-forum.com/t/array-invert/100192/4 "2005-12-13T17:11:31Z")

</div>

Beautiful, thank you David and Michael.  
Must be hard to improve now!

[David, Michael].merge :

class Array  
def invert  
res = []  
each\_with\_index do |e, i|  
e.each {|f| (res[f] ||= []) \<\< i} if e  
end  
res  
end  
end

Christer

---

<div class="post-metadata">

**Author:** ![christer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a5b964/32.png) [@christer](https://www.ruby-forum.com/u/christer)\
**Post date:** [December 13, 2005, 5:22pm UTC](https://www.ruby-forum.com/t/array-invert/100192/5 "2005-12-13T17:22:48Z")

</div>

Hash.invert exists, returning another Hash.

Is there any other interesting interpretation of Array.invert ?

(Matrix.invert is another thing 🙂

Is Array.invert useful enough to be a part of the original set of  
methods of Array?

I see two reasons for building in methods,  
the first one is to make programmer code faster,  
the second is to make code execute faster.

If Array.invert is seldom used and possible to execute fast, already in  
Ruby, there is no good reason to build it in.

Personally, I used Array.invert in finding solutions for kakuro.

Christer
