[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Getting array index for non-zero elements

Victor Reyes

4/29/2008 7:47:00 PM

[Note: parts of this message were removed to make it a legal post.]

Team,

Given multi-dimension array @ga:

@ga = [
[0,0,0,0,1,9,0,4,0],
[0,0,4,8,0,0,6,0,0],
[7,5,0,0,0,0,0,0,2],
[0,9,0,1,0,2,0,0,4],
[0,0,0,0,0,3,0,0,0],
[5,0,0,4,0,6,0,3,0],
[8,0,0,0,0,0,0,7,3],
[0,0,6,0,0,8,4,0,0],
[0,1,0,2,9,0,0,0,0]
]

I am able to find then non-zero elements of a particular row:

# If r = 0
rowArr = @ga[r]
puts rowArr
# Output: 0 0 0 0 1 9 0 4 0

nonzeroElements = rowArr.find_all {|e| e > 0}
puts nonzeroElements #
Output: 1 9 4

However, I don't actually want the elements, I would like to get the index
of those non-zero elements. I tried the following but it fails:

nonzeroIndex = rowArr.index rowArr.find_all {|e| e > 0}
puts
nonzeroIndex #
Output: *nil*

Any help will be greatly appreciated, as usual!

Thank you

Victor

5 Answers

Rob Biedenharn

4/29/2008 8:11:00 PM

0

On Apr 29, 2008, at 3:46 PM, Victor Reyes wrote:

> Team,
>
> Given multi-dimension array @ga:
>
> @ga = [
> [0,0,0,0,1,9,0,4,0],
> [0,0,4,8,0,0,6,0,0],
> [7,5,0,0,0,0,0,0,2],
> [0,9,0,1,0,2,0,0,4],
> [0,0,0,0,0,3,0,0,0],
> [5,0,0,4,0,6,0,3,0],
> [8,0,0,0,0,0,0,7,3],
> [0,0,6,0,0,8,4,0,0],
> [0,1,0,2,9,0,0,0,0]
> ]
>
> I am able to find then non-zero elements of a particular row:
>
> # If r = 0
> rowArr = @ga[r]
> puts rowArr
> # Output: 0 0 0 0 1 9 0 4 0
>
> nonzeroElements = rowArr.find_all {|e| e > 0}
> puts nonzeroElements #
> Output: 1 9 4
>
> However, I don't actually want the elements, I would like to get the
> index
> of those non-zero elements. I tried the following but it fails:
>
> nonzeroIndex = rowArr.index rowArr.find_all {|e| e > 0}
> puts
> nonzeroIndex
> #
> Output: *nil*
>
> Any help will be greatly appreciated, as usual!
>
> Thank you
>
> Victor



irb> require 'code/ruby/ext/enumerable.rb'
=> true
irb> @ga[0]
=> [0, 0, 0, 0, 1, 9, 0, 4, 0]
irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}
=> [nil, nil, nil, nil, 4, 5, nil, 7, nil]
irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}.compact
=> [4, 5, 7]

Then you just need Enumerable#map_with_index

module Enumerable
# Like each_with_index, but the value is the array of block results.
def map_with_index
a = []
each_with_index { |e,i| a << yield(e, i) }
a
end
end

-Rob

Rob Biedenharn http://agileconsult...
Rob@AgileConsultingLLC.com


Stefano Crocco

4/29/2008 8:11:00 PM

0

On Tuesday 29 April 2008, Victor Reyes wrote:
> However, I don't actually want the elements, I would like to get the index
> of those non-zero elements. I tried the following but it fails:
>
> =A0 =A0 =A0 =A0 =A0 nonzeroIndex =3D rowArr.index rowArr.find_all {|e| e =
> 0}
> =A0 =A0 =A0 =A0 =A0 puts
> nonzeroIndex =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0#
> Output: *nil*

Array#find_all returns an array containing all the elements for which the=20
block returns true. Since this array is not a member of rowArr, rowArr.inde=
x=20
returns nil.

The simplest way to achieve what you want, in my opinion, is the following:

require 'enumerator'

rowArr.enum_for(:each_index).find_all{|i| rowArr[i] > 0}

This creates an Enumerator (see ri Enumerator and ri enum_for) whose 'each'=
=20
method calls rowArr.each_index instead rowArr.each. The block is thus passe=
d=20
the index of the elements instead of the elements themselves, and the array=
=20
returned by findAll will contain the indexes of the items greater than 0.

I hope this helps

Stefano

Siep Korteling

4/29/2008 8:32:00 PM

0

Rob Biedenharn wrote:
> On Apr 29, 2008, at 3:46 PM, Victor Reyes wrote:
>
>> [5,0,0,4,0,6,0,3,0],
>> # Output: 0 0 0 0 1 9 0 4 0
>> puts
>> nonzeroIndex
>> #
>> Output: *nil*
>>
>> Any help will be greatly appreciated, as usual!
>>
>> Thank you
>>
>> Victor
>
>
>
> irb> require 'code/ruby/ext/enumerable.rb'
> => true
> irb> @ga[0]
> => [0, 0, 0, 0, 1, 9, 0, 4, 0]
> irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}
> => [nil, nil, nil, nil, 4, 5, nil, 7, nil]
> irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}.compact
> => [4, 5, 7]
>
> Then you just need Enumerable#map_with_index
>
> module Enumerable
> # Like each_with_index, but the value is the array of block results.
> def map_with_index
> a = []
> each_with_index { |e,i| a << yield(e, i) }
> a
> end
> end
>
> -Rob
>
> Rob Biedenharn http://agileconsult...
> Rob@AgileConsultingLLC.com

It works without the 'require' here.(VERSION=1.8.6). I like the
map_with_index method (new for me), but isn't it overkill here?

@ga.each do |sub_arr|
sub_arr.each_with_index do |value,index|
print index.to_s + " " unless value == 0
end
puts
end

Regards,

Siep
--
Posted via http://www.ruby-....

David A. Black

4/29/2008 8:38:00 PM

0

Hi --

On Wed, 30 Apr 2008, Siep Korteling wrote:

> Rob Biedenharn wrote:
>> On Apr 29, 2008, at 3:46 PM, Victor Reyes wrote:
>>
>>> [5,0,0,4,0,6,0,3,0],
>>> # Output: 0 0 0 0 1 9 0 4 0
>>> puts
>>> nonzeroIndex
>>> #
>>> Output: *nil*
>>>
>>> Any help will be greatly appreciated, as usual!
>>>
>>> Thank you
>>>
>>> Victor
>>
>>
>>
>> irb> require 'code/ruby/ext/enumerable.rb'
>> => true
>> irb> @ga[0]
>> => [0, 0, 0, 0, 1, 9, 0, 4, 0]
>> irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}
>> => [nil, nil, nil, nil, 4, 5, nil, 7, nil]
>> irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}.compact
>> => [4, 5, 7]
>>
>> Then you just need Enumerable#map_with_index
>>
>> module Enumerable
>> # Like each_with_index, but the value is the array of block results.
>> def map_with_index
>> a = []
>> each_with_index { |e,i| a << yield(e, i) }
>> a
>> end
>> end
>>
>> -Rob
>>
>> Rob Biedenharn http://agileconsult...
>> Rob@AgileConsultingLLC.com
>
> It works without the 'require' here.(VERSION=1.8.6). I like the
> map_with_index method (new for me), but isn't it overkill here?
>
> @ga.each do |sub_arr|
> sub_arr.each_with_index do |value,index|
> print index.to_s + " " unless value == 0
> end
> puts
> end

If all you need is side-effects, like printing, then you can used
#each (with_ or without index). #map_with_index, like #map itself,
returns a second collection.


David

--
Rails training from David A. Black and Ruby Power and Light:
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
INTRO TO RAILS June 24-27 London (Skills Matter)
See http://www.r... for details and updates!

Victor Reyes

4/30/2008 11:45:00 AM

0

[Note: parts of this message were removed to make it a legal post.]

Hi Team,

First, thank you for all your replies. I truly appreciate each and everyone
of them!
Generally speaking I have problems explaining in writing an idea or what I
intent to do.
But, let me try to explain what I would like to do.

I am trying to implement a sudoku algorithm.
Given an initial set of values which I represent as the following example:

@ga = [
[0,0,0,0,1,9,0,4,0],
[0,0,4,8,0,0,6,0,0],
[7,5,0,0,0,0,0,0,2],
[0,9,0,1,0,2,0,0,4],
[0,0,0,0,0,3,0,0,0],
[5,0,0,4,0,6,0,3,0],
[8,0,0,0,0,0,0,7,3],
[0,0,6,0,0,8,4,0,0],
[0,1,0,2,9,0,0,0,0]
]

I use the above array to propagate the given values to a "master" array
which contains ALL the ORIGINAL valid and possible entries for a location.
At the start all numbers from 1..9:
@aa = [

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789]
]

But I don't want to propagate the zeroes (0) from the given array. I use
zeroes (0) for convenience only.
So, for instance, from the given array please notice that there is a one (1)
at location @ga = [0][4].
Knowing the index of that non-zero value (1 in this case) I would then use
the same index on the so called master array to place the 1.
I will then proceed to eliminate all the ones (1) from the same row and
column, since, as I am sure you know, the rule of sudoku only allows a
particular number once in a given row and column.

Well, that's why I need the index, so I can a bit easier manipulate the
arrays and their contents.

Again, thank you for all your help.

Victor


On Tue, Apr 29, 2008 at 4:37 PM, David A. Black <dblack@rubypal.com> wrote:

> Hi --
>
>
> On Wed, 30 Apr 2008, Siep Korteling wrote:
>
> Rob Biedenharn wrote:
> >
> > > On Apr 29, 2008, at 3:46 PM, Victor Reyes wrote:
> > >
> > > [5,0,0,4,0,6,0,3,0],
> > > > # Output: 0 0 0 0 1 9 0 4 0
> > > > puts
> > > > nonzeroIndex
> > > > #
> > > > Output: *nil*
> > > >
> > > > Any help will be greatly appreciated, as usual!
> > > >
> > > > Thank you
> > > >
> > > > Victor
> > > >
> > >
> > >
> > >
> > > irb> require 'code/ruby/ext/enumerable.rb'
> > > => true
> > > irb> @ga[0]
> > > => [0, 0, 0, 0, 1, 9, 0, 4, 0]
> > > irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}
> > > => [nil, nil, nil, nil, 4, 5, nil, 7, nil]
> > > irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}.compact
> > > => [4, 5, 7]
> > >
> > > Then you just need Enumerable#map_with_index
> > >
> > > module Enumerable
> > > # Like each_with_index, but the value is the array of block results.
> > > def map_with_index
> > > a = []
> > > each_with_index { |e,i| a << yield(e, i) }
> > > a
> > > end
> > > end
> > >
> > > -Rob
> > >
> > > Rob Biedenharn http://agileconsult...
> > > Rob@AgileConsultingLLC.com
> > >
> >
> > It works without the 'require' here.(VERSION=1.8.6). I like the
> > map_with_index method (new for me), but isn't it overkill here?
> >
> > @ga.each do |sub_arr|
> > sub_arr.each_with_index do |value,index|
> > print index.to_s + " " unless value == 0
> > end
> > puts
> > end
> >
>
> If all you need is side-effects, like printing, then you can used
> #each (with_ or without index). #map_with_index, like #map itself,
> returns a second collection.
>
>
> David
>
> --
> Rails training from David A. Black and Ruby Power and Light:
> INTRO TO RAILS June 9-12 Berlin
> ADVANCING WITH RAILS June 16-19 Berlin
> INTRO TO RAILS June 24-27 London (Skills Matter)
> See http://www.r... for details and updates!
>
>