Array.invert

C

Christer Nilsson

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 != nil then
for b in self
res = [] if res.nil?
res << 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
 
D

dblack

Hi --

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
 
M

Michael Ulm

Christer said:
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 != nil then
for b in self
res = [] if res.nil?
res << 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

--
Michael Ulm
R&D Team
ISIS Information Systems Austria
tel: +43 2236 27551-219, fax: +43 2236 21081
e-mail: (e-mail address removed)
Visit our Website: www.isis-papyrus.com
 
C

Christer Nilsson

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
 
C

Christer Nilsson

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,270
Latest member
TopCryptoTwitterChannels_

Latest Threads

Top