how can we retrieve two variables in one line if else - ruby

("string" != "string") ? (article = '-' , contact_info = '-') : (article = '' , contact_info = '')
How can I update this condition then it will return two variables now its output is an array like ["-" , "-"]

I believe this should work:
article, contact_info = ("string" != "string") ? ['-', '-'] : ['' , '']
In ruby you can assign multiple variables from an array using:
Multiple Assignement

Just return arrays?
("string" != "string") ? ['-', '-'] : ['' , '']

Related

Laravel 5.1 blade, compare a var with many values

I want to compare a var with many values, like this:
{{(
((Request::segment(1) == 'A' || Request::segment(1) == 'B' || Request::segment(1) == 'ETC' || ... ) && $menu->link == 'XXX') ? 'visible' : ''
)}}
Is there a way to make the comparission with something like this?
{{(
((Request::segment(1) == my_values(A,B,C,E,...,ETC) && $menu->link == 'XXX') ? 'visible' : ''
)}}
I can't edit the values from Controller
What about using the PHP in_array as explained here ?
{{(
((in_array(Request::segment(1), ['A','B','C','E',...,'ETC']) && $menu->link == 'XXX') ? 'visible' : ''
)}}
you can use contains() function of laravel collection.
{{(
((collect(my_values(A,B,C,E,...,ETC))->contains(Request::segment(1)) && $menu->link == 'XXX') ? 'visible' : ''
)}}
Or you can use in_array method in PHP.
{{(
((in_array(Request::segment(1), ['A', 'B', 'C', 'ETC']) && $menu->link == 'XXX') ? 'visible' : ''
)) }}

why if condition is not working

I am testing small code below
params[:code] = if false
'N'
else
'Y'
end
it returns N for if param[:code] passed as true or false also rubucop shows error literal 'false' appeared in a condition. any idea why?
if false
params[:code] = if false
'N'
else
'Y'
end
This code is just :
params[:code] = 'Y'
No if, not but : false is well, always false, so there's no way N can be reached. That's the reason rubocop is complaining.
Modified code
I guess you meant to write :
params[:code] = if params[:code] == false
'N'
else
'Y'
end
It's not rubyish at all, but at least it looks like your code and does what you expect it to.
To test it :
params = {code: false}
params[:code] = if params[:code] == false
'N'
else
'Y'
end
p params
# {:code=>"N"}
Warning!
If your params values are Strings (as they often are), you'll have to test against Strings :
params[:code] = if params[:code] == "false"
'N'
else
'Y'
end
With a ternary :
params[:code] = params[:code] == "false" ? 'N' : 'Y'
Or a hash :
params[:code] = {'true' => 'Y', 'false' => 'N'}[params[:code]]
If you have a fuzzy input (e.g. true or "true" or "True" or "yes"), you could use Rails built-in methods to convert to boolean :
code = ActiveRecord::Type::Boolean.new.type_cast_from_database(params[:code]) # For Rails 4.2
params[:code] = code ? 'Y' : 'N'
Have you tried this...
params[:code] ? 'Y' : 'N'
Or
params[:code] = params[:code] ? 'Y' : 'N'
# If you are trying to also re-assign params[:code].

Multiple results in ? style if clause

I have the following code: i ? "x" : "y" But instead of only returning either "x" or "y" I also want to set i either true or false. i ? ("x"; i = false) : ("y"; i = true) however does not work.
(i ? "x" : "y").tap{i = !i}
or
(i = !i) ? "y" : "x"
But if this turns out to be an XY-situation (I don't write "XY-question" here because the OP has not asked any question), then this might be more elegant:
letter = ["x", "y"].cycle
letter.next #=> "x"
letter.next #=> "y"
letter.next #=> "x"
letter.next #=> "y"
...
If you want to return 'x' or y', then 'x' or 'y' needs to be the last statement:
i ? (i = false; 'x') : (i = true; 'y')
If you think of it like this, maybe it would make more sense:
if i
i = false
'x'
else
i = true
'y'
end
Keep in mind that setters in Ruby (and many other languages) return the value being set. For example, i = false returns false.
You should use ternary operator only in the simplest cases because readability and side-effect issues.
Ruby Code Style
But if you really want it you could do something like this:
!(i = !i) ? 'x' : 'y'

What is the syntax for array.select?

I'm trying to use Array.select to separate out, and then delete, strings from a database that contain unwanted items. I get no errors but this does not seem to be working as hoped.
The relevant code is the last part:
totaltext = []
masterfacs = ''
nilfacs = ''
roomfacs_hash = {'lcd' => lcd2, 'wifi'=> wifi2, 'wired' => wired2, 'ac' => ac2}
roomfacs_hash.each do |fac, fac_array|
if roomfacs.include? (fac)
totaltext = (totaltext + fac_array)
masterfacs = (masterfacs + fac + ' ')
else
nilfacs = (nilfacs + fac + ' ')
end
end
finaltext = Array.new
text_to_delete = totaltext2.select {|sentences| sentences =~ /#{nilfacs}/i}
finaltext = totaltext2.delete (text_to_delete)
puts finaltext
It's probably not working because delete isn't a chainable method (the return value is the object you are trying to delete on success, or nil if not found; not the modified array). To simplify your code, just use reject
finaltext = totaltext.reject{|sentence| nilfacs.any?{|fac| sentence =~ /#{fac}/i } }

Ternary operator

I have an array d = ['foo', 'bar', 'baz'], and want to put its elements together into a string delimited by , and and at the last element so that it will become foo, bar and baz.
Here is what I'm trying to do:
s = ''
d.each_with_index { |x,i|
s << x
s << i < d.length - 1? i == d.length - 2 ? ' and ' : ', ' : ''
}
but the interpreter gives an error:
`<': comparison of String with 2 failed (ArgumentError)
However, it works with += instead of <<, but the Ruby Cookbook says that:
If efficiency is important to you, don't build a new string when you can append items onto an existing string. [And so on]... Use str << var1 << ' ' << var2 instead.
Is it possible without += in this case?
Also, there has to be a more elegant way of doing this than the code above.
You're just missing some parenthesis:
d = ['foo', 'bar', 'baz']
s = ''
d.each_with_index { |x,i|
s << x
s << (i < d.length - 1? (i == d.length - 2 ? ' and ' : ', ') : '')
}
I'd find
s << i < d.length - 1? i == d.length - 2 ? ' and ' : ', ' : ''
hard to read or maintain.
I'd probably change it to
join = case
when i < d.length - 2 then ", "
when i == d.length - 2 then " and "
when i == d.length then ""
end
s << join
Or possibly do
earlier_elements = d[0..-2].join(", ")
s = [earlier_elements, d[-1..-1]].join(" and ")
Or
joins = [", "] * (d.length - 2) + [" and "]
s = d.zip(joins).map(&:join).join
So much simpler like this:
"#{d[0...-1].join(", ")} and #{d.last}"

Resources