Help

hi Gurus,

Here my data structure

1234 => { ‘open’ => ‘1234-1’,
‘analyzed’ => ‘1234-2’,
‘feedback’ => ‘1234-3’,
‘closed’ => ‘1234-4’
}
3455 => { ‘open’ => ‘3455-1’,
‘analyzed’ => ‘34552’,
‘feedback’ => ‘3455-3’,
‘closed’ => ‘3455-4’
}

My task is to display numbers [like 1234 or 3455] if they have (‘open’
OR ‘analyzed’) AND (‘closed’ OR ‘feedback’) keys. I tried following
code

puts numbers if $DATA[pr].has_key?( ( (‘closed’ || ‘feedback’)
&& (‘open’ ||
‘analyzed’) ) )

I am not sure what is wrong with it but its not testing these
conditions and printing all numbers. Please help me understanding
has_key method and writing correct condition.

Thanks

On Thu, Jan 7, 2010 at 10:20 AM, Jagadeesh [email protected]
wrote:

          'analyzed' => '34552',

‘analyzed’) ) )

I am not sure what is wrong with it but its not testing these
conditions and printing all numbers. Please help me understanding
has_key method and writing correct condition.

The has_key? method receives a single key to be checked in the hash.
In your snippet, what you are passing to the has_key? method is the
result of evaluating this:

( (‘closed’ || ‘feedback’) && (‘open’ || ‘analyzed’) )

which is:

irb(main):002:0> ( (‘closed’ || ‘feedback’) && (‘open’ || ‘analyzed’) )
=> “open”

So you are testing only for the “open” key. I don’t know what $DATA or
pr or numbers are in your snippet, but you are testing only for the
key “open”.

Hope this helps,

Jesus.

On Thursday 07 January 2010, Jagadeesh wrote:

| ‘analyzed’ => ‘34552’,
|‘analyzed’) ) )
|
|I am not sure what is wrong with it but its not testing these
|conditions and printing all numbers. Please help me understanding
|has_key method and writing correct condition.
|
|Thanks

Not tested, but I think the condition should be:

($DATA[pr].has_key?(‘closed’) || $DATA[pr].has_key?(‘feedback’)) &&
($DATA[pr].has_key?(‘open’) || $DATA[pr].has_key?(‘analyzed’))

Your condition would always have translated to

if $DATA[pr].has_key?(‘open’)

This happens because ruby first evaluates the argument to has_key? and
because
of the way logical operators work. || returns the first operand which
evaluates to true (that is, the first operand which is not false or
nil). This
means that:
‘closed’ || ‘feedback’ always gives ‘closed’
‘open’ || ‘analyzed’ always gives ‘open’

On the other hand, the && operator returns the last operand if both
evaluate
to true and the value of the one which evaluates to false if one
evaluates to
false (if both evaluate to false, it returns the first). In your case,
you had
the expression

‘closed’ && ‘open’

which evaluates to ‘open’.

I hope this helps

Stefano

Here is how I am trying to do with array

states = [‘open’, ‘analyzed’, ‘feedback’, ‘closed’]

unless ( ( states.grep(‘closed’).empty? || states.grep
(‘feedback’).empty? )
&& (states.grep(‘open’).empty? ||states.grep
(‘analyzed’).empty? ) )
puts “hello”
end

Thanks

On Jan 7, 2:36 pm, Stefano C. [email protected] wrote:

| ‘feedback’ => ‘1234-3’,
|code

of the way logical operators work. || returns the first operand which
‘closed’ && ‘open’

which evaluates to ‘open’.

I hope this helps

Stefano

Thank you so much for crystal clear explanation. Would you show me how
I can do it using array? I tried using grep but did not get good
result.

I want to print if I find (closed or feedback) and (open or analyzed)
keys.

Thanks

On Thu, Jan 7, 2010 at 10:55 AM, Jagadeesh [email protected]
wrote:

          'closed' => '1234-4'

result of evaluating this:
key “open”.
‘3455’ => { ‘open’ => ‘3455-1’,
‘analyzed’ => ‘34552’,
‘feedback’ => ‘3455-3’,
‘closed’ => ‘3455-4’
}
}

and am reading it in loop so pr will have 1234, 3455 etc.

As Stefano said:

irb(main):001:0> $DATA = {
irb(main):002:1* 1234 => { ‘open’ => ‘1234-1’,
irb(main):003:2* ‘analyzed’ => ‘1234-2’,
irb(main):004:2* ‘feedback’ => ‘1234-3’,
irb(main):005:2* ‘closed’ => ‘1234-4’
irb(main):006:2> },
irb(main):007:1* 3455 => { ‘open’ => ‘3455-1’,
irb(main):008:2* ‘analyzed’ => ‘34552’,
irb(main):009:2* ‘feedback’ => ‘3455-3’,
irb(main):010:2* ‘closed’ => ‘3455-4’
irb(main):011:2> }}
=> {3455=>{“open”=>“3455-1”, “analyzed”=>“34552”, “closed”=>“3455-4”,
“feedback”=>“3455-3”}, 1234=>{“open”=>“1234-1”, “analyzed”=>“1234-2”,
“closed”=>“1234-4”, “feedback”=>“1234-3”}}
irb(main):012:0> $DATA.each do |k,v|
irb(main):013:1* puts k if ( (v.has_key?(‘closed’) ||
v.has_key?(‘feedback’)) && ((v.has_key?(‘open’) ||
v.has_key?(‘analyzed’))))
irb(main):014:1> end
3455
1234

Hope this helps,

Jesus.

On Thursday 07 January 2010, Jagadeesh wrote:

|> > | ‘closed’ => ‘1234-4’
|> > |(‘open’ OR ‘analyzed’) AND (‘closed’ OR ‘feedback’) keys. I tried
|> > |conditions and printing all numbers. Please help me understanding
|>
|> evaluate to true and the value of the one which evaluates to false if
|
|Thank you so much for crystal clear explanation. Would you show me how
|I can do it using array? I tried using grep but did not get good
|result.
|
|I want to print if I find (closed or feedback) and (open or analyzed)
|keys.
|
|Thanks

I’m not sure about what you mean by “using array?”. Your code clearly
uses a
hash, and Array has no keys and, obviously, no has_key? method. Looking
at
your reply to Jesús, I’d say what you want is this:

$DATA.each_pair do |key, value|
if (value.has_key?(‘closed’) || value.has_key?(‘feedback’)) &&
(value.has_key?(‘open’) || value.has_key?(‘analyzed’))
puts key
end
end

Hash#each_pair calls the block for each key-value pair. The first
argument of
the block will be set to the key; the second will be set to the value.

If you’re sure the values associated with the ‘closed’, ‘feedback’,
‘open’ and
‘analyzed’ keys will never be nil or false, you can replace the
condition with
this:

if (value[‘closed’] || value[‘feedback’]) && (value[‘open’] ||
value[‘analyzed’])

This way, instead of checking whether the hash has a given key, you
check
whether or not the associated value is nil. Since Hash returns nil if
you ask
for a non existing key, you’ll get a true value (in your case, a string)
if
the key exists and nil if it doesn’t. This means you get a true value
when
has_key? would have returned true and a false value (nil) when has_key?
would
have returned false. This, of course, breaks if a key can correspond to
a
value which is false or nil.

Stefano

On Jan 7, 2:33 pm, Jesús Gabriel y Galán [email protected]
wrote:

3455 => { ‘open’ => ‘3455-1’,
&& (‘open’ ||
( (‘closed’ || ‘feedback’) && (‘open’ || ‘analyzed’) )
Hope this helps,

Jesus.

$DATA=>{‘1234’ => { ‘open’ => ‘1234-1’,
‘analyzed’ => ‘1234-2’,
‘feedback’ => ‘1234-3’,
‘closed’ => ‘1234-4’
},
‘3455’ => { ‘open’ => ‘3455-1’,
‘analyzed’ => ‘34552’,
‘feedback’ => ‘3455-3’,
‘closed’ => ‘3455-4’
}
}

and am reading it in loop so pr will have 1234, 3455 etc.

Thanks for your help.

Thanks

On Jan 7, 3:08 pm, Jesús Gabriel y Galán [email protected]
wrote:

          'feedback' => '1234-3',

code
In your snippet, what you are passing to the has_key? method is the
pr or numbers are in your snippet, but you are testing only for the
},

irb(main):011:2> }}

Hope this helps,

Jesus.

Thank you so much. It is working now.

Thanks for all your help.

Thanks

On Thursday 07 January 2010, Jagadeesh wrote:

|
|Thanks

Still I don’t understand exactly what you’re trying to do. states
contains all
the four entries, so states.grep will never return an empty array and
the puts
will always be executed.

Please, can you explain in detail what you’re trying to do? This way
we’ll be
able to help you better.

Stefano