[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

An array problem

George George

4/2/2009 3:48:00 PM

Hi
i have a 3 arrays(A,B,C) which are results of some analysis.
Array A has all members such that array B and C are actually subsets of
A. The order of elements in array A is important.

What i want is to list all members of A such that if an element in A is
a found in B or C produce a report such as

element1 -b
element2 -b
element3 -c
element4 -b
....

where the order of elements in the report is as was in array A.


my rather silly implentation was
A.each do |element|
if B.detect(element)
puts "#{element}- b"
end
end

however i don't think this is the right way to do it since it does not
give me the designed result. Can someone help me spot the bug?

Thank you
George
--
Posted via http://www.ruby-....

8 Answers

Robert Klemme

4/2/2009 4:23:00 PM

0

2009/4/2 George George <george.githinji@gmail.com>:

> i have a 3 arrays(A,B,C) which are results of some analysis.

I'd rather not make those constants (A,B,C) because they aren't as you stat=
ed.

> Array A has all members such that array B and C are actually subsets of
> A. The order of elements in array A is important.
>
> What i want is to list all members of A such that if an element in A is
> a found in B or C produce a report such as
>
> element1 -b
> element2 -b
> element3 -c
> element4 -b
> ....
>
> where the order of elements in the report is as was in array A.
>
>
> my rather silly implentation was
> A.each do |element|
> =A0if B.detect(element)
> =A0 =A0puts "#{element}- b"
> =A0end
> end
>
> however i don't think this is the right way to do it since it does not
> give me the designed result. Can someone help me spot the bug?

You want #include? instead of #detect:

a.each do |el|
case
when b.include? el
puts "#{el} -b"
when c.include? el
puts "#{el} -c"
end
end

Another hint: if A is really large (say 10_000 elements or more) it
might be more efficient to convert B and C into Sets which have faster
inclusion test.

Or do it this way:

occurrences =3D {}

{b =3D> "b", c =3D> "c"}.each do |ar,label|
ar.each {|el| occurrences[el] =3D label}
end

a.each do |el|
label =3D occurrences[el] and
puts "#{el} -#{label}"
end

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end

George George

4/3/2009 5:09:00 AM

0


>
> You want #include? instead of #detect:
>
> a.each do |el|
> case
> when b.include? el
> puts "#{el} -b"
> when c.include? el
> puts "#{el} -c"
> end
> end

Thanks a lot Robert, However this solution does not seem to preserve the
order in of array a.
for example if array a contained
a = ["x","y","z","f"]
b = ["y","z"]
c = ["x","f"]

the result should be

x-c
y-b
z-b
f-c

Thanks
GG



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

Robert Klemme

4/3/2009 6:28:00 AM

0

On 03.04.2009 07:09, George George wrote:
>> You want #include? instead of #detect:
>>
>> a.each do |el|
>> case
>> when b.include? el
>> puts "#{el} -b"
>> when c.include? el
>> puts "#{el} -c"
>> end
>> end
>
> Thanks a lot Robert, However this solution does not seem to preserve the
> order in of array a.
> for example if array a contained
> a = ["x","y","z","f"]
> b = ["y","z"]
> c = ["x","f"]
>
> the result should be
>
> x-c
> y-b
> z-b
> f-c

I don't see how the order in a could not be preserved. Please check
again oder provide full code.

Kind regards

robert

George George

4/3/2009 8:17:00 AM

0

Robert Klemme wrote:

> I don't see how the order in a could not be preserved. Please check
> again oder provide full code.

Here is the code
#original list
@list_of_names

#mcl.total_clusters provides a count for the number of clusters #or
arrays available(a.k.a, my b and c in the previous #descriptions)

#an iterator that counts the number of arrays available(subsets #of
@cluster_members
mcl.total_clusters.times do |i|
cluster_members = mcl.cluster_members_for(i)

@list_of_names.each do |el|
case
when cluster_members.include?(el)
puts "#{el} - #{i}"
end
end
end

Given: @list_of_names =
[10Atig18,10Atig8,10Atig7,10Atig3,10Btig15,10Btig11,10Btig1],


and cluster b=[10Atig8,10Atig3,10Btig1] while the rest of the members
belonged to cluster c

produce a report such that
10Atig18 -c
10Atig8 -b
10Atig7 -c
10Atig3 -b
10Btig15 -c
10Btig11 -c
10Btig1 -b

The implementation above produces this,
10Atig8 -b
10Atig3 -b
10Btig1 -b
10Atig18 -c
10Atig7 -c
10Btig15 -c
10Btig11 -c

which is not what is required.
--
Posted via http://www.ruby-....

Robert Klemme

4/3/2009 8:36:00 AM

0

On 03.04.2009 10:17, George George wrote:
> Robert Klemme wrote:
>
>> I don't see how the order in a could not be preserved. Please check
>> again oder provide full code.
>
> Here is the code
> #original list
> @list_of_names
>
> #mcl.total_clusters provides a count for the number of clusters #or
> arrays available(a.k.a, my b and c in the previous #descriptions)
>
> #an iterator that counts the number of arrays available(subsets #of
> @cluster_members
> mcl.total_clusters.times do |i|
> cluster_members = mcl.cluster_members_for(i)
>
> @list_of_names.each do |el|
> case
> when cluster_members.include?(el)
> puts "#{el} - #{i}"
> end
> end
> end
>
> Given: @list_of_names =
> [10Atig18,10Atig8,10Atig7,10Atig3,10Btig15,10Btig11,10Btig1],
>
>
> and cluster b=[10Atig8,10Atig3,10Btig1] while the rest of the members
> belonged to cluster c
>
> produce a report such that
> 10Atig18 -c
> 10Atig8 -b
> 10Atig7 -c
> 10Atig3 -b
> 10Btig15 -c
> 10Btig11 -c
> 10Btig1 -b
>
> The implementation above produces this,
> 10Atig8 -b
> 10Atig3 -b
> 10Btig1 -b
> 10Atig18 -c
> 10Atig7 -c
> 10Btig15 -c
> 10Btig11 -c
>
> which is not what is required.

George, you claimed that the code *I* presented does not maintain order.
Now you present totally different code as "proof". The error is in
*your* code. Btw, you also did not state that the number of cluster
arrays (b and c) is not fixed which is of course why you could not use
the bit you claimed would not maintain order. Please go back to my
original posting - you'll find building blocks for a solution there.
I'll leave the rest to you.

Regards

robert

George George

4/3/2009 8:55:00 AM

0

Robert Klemme wrote:

>
> George, you claimed that the code *I* presented does not maintain order.
> Now you present totally different code as "proof". The error is in
> *your* code. Btw, you also did not state that the number of cluster
> arrays (b and c) is not fixed which is of course why you could not use
> the bit you claimed would not maintain order. Please go back to my
> original posting - you'll find building blocks for a solution there.
> I'll leave the rest to you.


True, the error is in my code. Thank you for providing the clues.
--
Posted via http://www.ruby-....

Christopher Dicely

4/3/2009 3:04:00 PM

0

On Thu, Apr 2, 2009 at 9:23 AM, Robert Klemme
<shortcutter@googlemail.com> wrote:
> 2009/4/2 George George <george.githinji@gmail.com>:
>
>> i have a 3 arrays(A,B,C) which are results of some analysis.
>
> I'd rather not make those constants (A,B,C) because they aren't as you st=
ated.
>
>> Array A has all members such that array B and C are actually subsets of
>> A. The order of elements in array A is important.
>>
>> What i want is to list all members of A such that if an element in A is
>> a found in B or C produce a report such as
>>
>> element1 -b
>> element2 -b
>> element3 -c
>> element4 -b
>> ....
>>
>> where the order of elements in the report is as was in array A.
>>
>>
>> my rather silly implentation was
>> A.each do |element|
>> =C2=A0if B.detect(element)
>> =C2=A0 =C2=A0puts "#{element}- b"
>> =C2=A0end
>> end
>>
>> however i don't think this is the right way to do it since it does not
>> give me the designed result. Can someone help me spot the bug?
>
> You want #include? instead of #detect:
>
> a.each do |el|
> =C2=A0case
> =C2=A0 =C2=A0when b.include? el
> =C2=A0 =C2=A0 =C2=A0puts "#{el} -b"
> =C2=A0 =C2=A0when c.include? el
> =C2=A0 =C2=A0 =C2=A0puts "#{el} -c"
> =C2=A0end
> end

Neither ruby 1.8.6 (in IRB) or Jruby 1.2.0 (in jirb_swing) likes this
without parenthesizing the argument to include? in the when clauses,
but a bigger problem is that if both b and c include a value it will
only print that b did, since when clauses are exclusive.

If its not essential to preprocess the arrays as in your second
approach, the following works:

puts a.map { |el|
{b=3D>'b',c=3D>'c'}.map { |arr, label|
"#{el} -#{label}" if arr.include?(el)
}
}.flatten.compact

Robert Klemme

4/3/2009 4:18:00 PM

0

On 03.04.2009 17:03, Christopher Dicely wrote:
> On Thu, Apr 2, 2009 at 9:23 AM, Robert Klemme
> <shortcutter@googlemail.com> wrote:
>> 2009/4/2 George George <george.githinji@gmail.com>:
>>
>>> i have a 3 arrays(A,B,C) which are results of some analysis.
>> I'd rather not make those constants (A,B,C) because they aren't as you stated.
>>
>>> Array A has all members such that array B and C are actually subsets of
>>> A. The order of elements in array A is important.
>>>
>>> What i want is to list all members of A such that if an element in A is
>>> a found in B or C produce a report such as
>>>
>>> element1 -b
>>> element2 -b
>>> element3 -c
>>> element4 -b
>>> ....
>>>
>>> where the order of elements in the report is as was in array A.
>>>
>>>
>>> my rather silly implentation was
>>> A.each do |element|
>>> if B.detect(element)
>>> puts "#{element}- b"
>>> end
>>> end
>>>
>>> however i don't think this is the right way to do it since it does not
>>> give me the designed result. Can someone help me spot the bug?
>> You want #include? instead of #detect:
>>
>> a.each do |el|
>> case
>> when b.include? el
>> puts "#{el} -b"
>> when c.include? el
>> puts "#{el} -c"
>> end
>> end
>
> Neither ruby 1.8.6 (in IRB) or Jruby 1.2.0 (in jirb_swing) likes this
> without parenthesizing the argument to include? in the when clauses,

Right, I should have made the check. Thank you for pointing this out.

> but a bigger problem is that if both b and c include a value it will
> only print that b did, since when clauses are exclusive.

This is not a problem of my code but in the problem specification.
There was no statement about whether elements can occur in multiple of
the subsets and if so, whether there is any priority defined. Since
maintaining original order was stated important reporting an element
more than once was not an option for me.

> If its not essential to preprocess the arrays as in your second
> approach, the following works:
>
> puts a.map { |el|
> {b=>'b',c=>'c'}.map { |arr, label|
> "#{el} -#{label}" if arr.include?(el)
> }
> }.flatten.compact

I always find it inelegant to produce nested Arrays which can contain
nils and then getting rid of them using flatten and compact. That's
mostly an issue of personal taste but in cases where there can be many
nils compared to non nils this is also about efficiency.

Apropos: in your code you'll create the same Hashes all the time. You
could at least factor that out.

Kind regards

robert