Array.invert

Hi Christer,

don't take this to serious:

a = [[1,3],[1,4,5]]
p (0...a.size).zip(a).inject(){|s, b| b[1].each{|i| (s[i] ||= ) <<
b[0]}; s}

=> [nil, [0, 1], nil, [0], [1], [1]]

cheers

Simon

···

From: list-bounce@example.com
[mailto:list-bounce@example.com] On Behalf Of Christer Nilsson
Sent: Tuesday, December 13, 2005 3:44 PM
To: ruby-talk ML
Subject: Array.invert

I would like to see invert "rubyfied".
(Yes, I'm trying to get a grip of what this word means :slight_smile:

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

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

Kroeger, Simon (ext) wrote:

Hi Christer,

don't take this to serious:

a = [[1,3],[1,4,5]]
p (0...a.size).zip(a).inject(){|s, b| b[1].each{|i| (s[i] ||= ) <<
b[0]}; s}

=> [nil, [0, 1], nil, [0], [1], [1]]

cheers

Simon

Is it possible to wrap this in a method ?
I tried but I get a nil.each error.

Christer

···

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

Kroeger, Simon (ext) wrote:

Hi Christer,

don't take this to serious:

a = [[1,3],[1,4,5]]
p (0...a.size).zip(a).inject(){|s, b| b[1].each{|i| (s[i] ||= ) <<
b[0]}; s}

=> [nil, [0, 1], nil, [0], [1], [1]]

cheers

Simon

Ruby is so fun, it's impossible to be serious :slight_smile:

a.invert works but not a.invert.invert

Can you fix that in your amazing oneliner ?
Clue: nil.each is the bummer.

Christer

···

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

Christer Nilsson wrote:

Kroeger, Simon (ext) wrote:

Hi Christer,

don't take this to serious:

a = [[1,3],[1,4,5]]
p (0...a.size).zip(a).inject(){|s, b| b[1].each{|i| (s[i] ||= ) <<
b[0]}; s}

=> [nil, [0, 1], nil, [0], [1], [1]]

cheers

Simon

Ruby is so fun, it's impossible to be serious :slight_smile:

a.invert works but not a.invert.invert

Can you fix that in your amazing oneliner ?
Clue: nil.each is the bummer.

Christer

rofl!

i will give you two:

class Array
   def invert
     zip([*(0...size)]).inject(){|s, b| (b.first || ).each{|i| (s[i]

= ) << b.last}; s}

   end
end

or (even worse):

class Array
   def invert
     Array.new(flatten.compact.max.succ){|i| zip([*(0...size)]).find_all{|b, j| b && b.include?(i)}.transpose[1]}
   end
end

cheers

Simon

Hi --

···

On Wed, 14 Dec 2005, Simon Kröger wrote:

Christer Nilsson wrote:

Kroeger, Simon (ext) wrote:

Hi Christer,

don't take this to serious:

a = [[1,3],[1,4,5]]
p (0...a.size).zip(a).inject(){|s, b| b[1].each{|i| (s[i] ||= ) <<
b[0]}; s}

=> [nil, [0, 1], nil, [0], [1], [1]]

cheers

Simon

Ruby is so fun, it's impossible to be serious :slight_smile:

a.invert works but not a.invert.invert

Can you fix that in your amazing oneliner ?
Clue: nil.each is the bummer.

Christer

rofl!

i will give you two:

class Array
def invert
   zip([*(0...size)]).inject(){|s, b| (b.first || ).each{|i| (s[i] ||= ) << b.last}; s}
end
end

You could also do: b.first.to_a, which will be for nil and self if
b.first is an array.

David

--
David A. Black
dblack@wobblini.net

"Ruby for Rails", forthcoming from Manning Publications, April 2006!

Simon wrote:

i will give you two:

class Array
   def invert
     zip([*(0...size)]).inject(){|s, b| (b.first || ).each{|i| (s[i]
>>= ) << b.last}; s}
   end
end

or (even worse):

class Array
   def invert
     Array.new(flatten.compact.max.succ){|i|
zip([*(0...size)]).find_all{|b, j| b && b.include?(i)}.transpose[1]}
   end
end

I didn't know invert was so complex that ten keywords were needed!
The more keywords, the more cycles.
My original old fashioned fortran style polyliner is still quickest :slight_smile:

Christer

···

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