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