Equality test on three or more objects - ruby

If I have three or more objects like so:
a = 4
b = 4
c = 4
d = 2
what would be a clean ruby-style way of determining whether they are all equal? Any bespoke methods for running equality tests on three or more elements?
I suppose I could do something like this:
arrays = [a,b,c,d].map{|x| [x]}
arrays.first == arrays.reduce(:&) ? true : false
which appears to work, but feels sort of ham handed, and might be difficult for other developers to read.

[a,b,c,d].any?{|x| x != a}
or
array.any?{|x| x != array.first}
Alternatively, the #all? method may read more intuitively for some:
array.all? {|x| x == array.first }

[a, b, c, d].group_by(&:itself).length == 1
# => false
or
[a, b, c, d].chunk(&:itself).to_a.length == 1
# => false
or
[a, b, c, d].chunk_while(&:==).to_a.length == 1
# => false
or the naive:
[a, b, c, d].uniq.length == 1
I was reminded of one?. Provided that you do not have any falsy element, the above can be written:
[a, b, c, d].uniq.length.one?

I think the answer by #kipar is better by all means, but for the sake of “doing it the way you started” I would post this here:
[a, b, c, d].reduce { |r, e| r == e && r } && true

Related

Algorithm: generate list permutation by preference

I have a function f that takes a list of items as it's single parameter and returns true if the ordering of the items is accepted or false if the ordering of the items is not accepted.
There exists at least one or more permutations of list l which f(l) returns true.
Function f is a black box (we don't have it's source code) and the type of the elements held by list l are also unknown or generic.
p is a permutation of list l according to user preferences. The most preferred item has index 0 the least preferred item has index l.size()-1
list p will always contain all elements of list l.
The goal is to find a permutation of l let's call it p_accepted where f(p_accepted) returns true and preference p is maximized.
Here's an example
given l = [a, b, c, d, e, f]
given p = [c, a, f, b, e, d]
given f([ a, b, c, d, e, f ]) = false
given f([ c, a, f, b, e, d ]) = false
given f([ d, e, b, f, a, c ]) = true
given f([ f, e, d, c, b, a ]) = true
given f([ c, b, f, a, d, e ]) = true
given f([ a, c, f, b, e, d ]) = true
given f([ anything else ]) = false
the expected output for p_accepted is [c, b, f, a, d, e]
it is accepted because f(p_accepted) returns true and no other permutation of l ranks the item 'c' as high. item 'c' is the most preferred by the user since it has index 0
Implementations in pseudo code or any language are accepted.
[EDIT]
Clarifications
list p will always contain all elements of list l
list l items can only be compared by identity, i.e.: by reference
so an item in list p can be found in list l by l[i] == p[j]
list l items cannot always be compared like in the example where a compare function c might determine that a < b i.e.: c('a', 'b') = 1.
[EDIT 2]
To understand preferences better
Imagine Alice and Bob being forced to do 4 tasks together at the same time in order. [task a, task b, task c, task d].
Alice has one preferred order for doing the tasks [a,b,c,d]. Bob has two preferred orders for doing the tasks [a,c,b,d], [a,d,b,c]. If you are Alice, the function f would return true only for [a,c,b,d] and [a,d,b,c] which are Bob's preferences, since both like to do task a first p_accepted should start with a.
Note that this is an analogy function f does not accept permutations based on multiple user's order preference.

Why does this method return three values?

I have following Ruby programm:
def swap (a,b)
return a,b = b,a
end
puts swap(5,3)
I expected the output.
3
5
But I get.
5
3
5
What's the reason?
Thanks!
Why does this method return three values?
It's because of the return statement, Ruby tries to interpret the right-hand side as an array and your code:
return a,b = b,a
gets evaluated as: (parentheses added for clarity)
return [a, (b=b), a]
i.e. a 3-element array [a, b, a] (assigning b to itself does nothing)
Remove the keyword return. It is actually doing: return a, (b), a. Where (b = b)
def swap(a,b)
a, b = b, a
end
puts swap(5,3)
Output
=> 3, 5
In your program: in swap function the return you have given is return a,b = b,a
remove a,band diretcly write return b,a.
you will get your expected output.
Reason:
in return a,b = b,a is return first the value of a then executing b=b,a.
Hope this might help you out
def swap (a,b)
return b,a
end
puts swap(5,3)
Output
3
5

Ruby boolean logic: some amount of variables are true

Let say I have 3 variables: a, b, c.
How can I check that just zero or one of them is true?
[a, b, c].count(true) < 2
.....................

How can I get "x" objects before a given object?

It's better to explain this in pseudo-code, I want to do this:
limit_object = Model.first(id: bla)
objects = Model.all(constraint: limit_object, limit: 30)
If the objects are:
[a, b, c, d, e, f, g]
and limit_object is 'c', it should return:
[a, b, c]
Is there a way to do this in DataMapper?
Okay, I found it:
quotes = Model.all(:for_date.lte => date, limit: 10)

How to initialize objects with different object_id in Ruby?

If I initialize objects with assignment like a = b = c = []
then this variables have the same object_ids: a.object_id == b.object_id == c.object_id
Also I tried:
[a, b, c].map {|e| e = [] }
a, b, c = Array.new(3, [])
a, b, c = Array.new(3, Array.new)
but it doensn't initialize a, b, c variables with different object_ids
Is there a way to initialize variables a, b, c with different object ids but with the same value == []?
How about these possible solutions:
a,b,c=[],[],[]
a,b,c=(0..2).map{[]}
a,b,c=Array.new(3){[]}
How about this?
a = []
b = []
c = []

Resources