Why does uniq return original value of array after map in Ruby?

Related searches

I tried the following code:

numbers = [1,2,2,3,4]
numbers.map.uniq {|number| number < 2 }

My understanding is that the return value of map is passed to uniq. I expected:

[true, false]

Instead, I received:

[1, 2]

It seems that uniq maintains a reference to the original array.

Could someone provide insight into this behaviour?

Array#uniq accepts a block, defining the condition on what should be treated uniq.

main > numbers = [1,2,2,3,4].map
#⇒ #<Enumerator: ...>
main > numbers.uniq
#⇒ [1, 2, 3, 4]

# effectively the same as
main > numbers.to_a.uniq
#⇒ [1, 2, 3, 4]

main > numbers.uniq { |number| number.odd? }
#⇒ [1, 2]

The latter returns one odd and one non-odd (even) element. In your case it returns 1 element that is less than 2 and one element that is greater or equal to two.


Note, that map enumerator is effectively there:

numbers.each &Math.method(:sqrt)
#⇒ [1.0, 1.4142135623730951, 1.4142135623730951,
#        1.7320508075688772, 2.0]

How to Use The Ruby Uniq Method To Remove Duplicates, Calling uniq on this array removes the extra ones & returns a NEW array with unique numbers. Notice that uniq won't change n (the original array), so we need to either call uniq! Because hash keys are unique, we can get a list of all the keys in the hash, this list Ruby takes the values & returns them as a new array. 1 Ruby regex replace substring with hash pattern Feb 6 '19. -1 Why does uniq return original value of array after map in Ruby? Mar 19 '19. Badges (7)

You're not actually doing anything with the map call, your function is roughly equivalent to this:

[1,2,2,3,4].uniq {|number| p number < 2 }

Methods like map return an Enumerable type, and you are then calling uniq on that Enumerable. From the Ruby docs:

If no block is given, an Enumerator is returned instead.

Effectively your map is a no-op.

I think you're also misunderstanding the uniq method. Uniq is going to filter out any elements from an array that aren't unique (eg: [1, 1, 2, 3, 3, 4, 5].uniq == [1, 2, 3, 4, 5]), not return whether the element is unique (true or false) in the array.

More than you care to know about the uniq method, This is a pretty common method; provided you aren't completely new to Ruby, are treated distinctly and do not reduce to a single object in the returned array. the original point of this article… you can pass a block as a parameter to the uniq Using `values` instead of the first `map` would make this code more semantic� Sometimes you’ll get lists of data that have some duplication. You could iterate through the array and filter out the duplicates, but Ruby’s uniq method makes that a lot easier. The uniq method returns a new array with all duplicate values removed. [1,2,3,4,1,5,3].uniq # [1,2,3,4,5]

numbers.uniq.map { |number| number < 2 }

uniq method

uniq → new_ary click to toggle source uniq {|item| ...} → new_ary Returns a new array by removing duplicate values in self.

If a block is given, it will use the return value of the block for comparison. It compares values using their hash and eql? methods for efficiency. self is traversed in order, and the first occurrence is kept.

a = [ "a", "a", "b", "b", "c" ]

a.uniq # => ["a", "b", "c"]

b = [["student","sam"], ["student","george"], ["teacher","matz"]]

b.uniq {|s| s.first} # => [["student", "sam"], ["teacher", "matz"]]

You can read more about uniq method here.

class Array - Documentation for Ruby 2.0.0, drop does the opposite of take, by returning the elements after n elements have A useful method if you need to remove nil values from an array is compact: arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556] arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123] The map method can be used to create a new array based on the original array, but� What is Rack::Utils.multipart_part_limit within Rails and what function does it perform? ruby-on-rails,ruby,rack,multipart. Telling it short, this value limits the amount of simultaneously opened files for multipart requests. To understand better what is multipart, you can see this question.

Class: Array (Ruby 2.5.0), drop does the opposite of take, by returning the elements after n elements have been dropped: A useful method if you need to remove nil values from an array is compact: It has the non-destructive uniq, and destructive method uniq! The map method can be used to create a new array based on the original array, but� Definition and Usage. The join() method returns the array as a string.. The elements will be separated by a specified separator. The default separator is comma (,). Note: this method will not change the original array.

How To Use Array Methods in Ruby, These methods often have side-effects, such as mutating the original value, the array and filter out the duplicates, but Ruby's uniq method makes that a lot easier. Since map returns a new array, the array can then be transformed and� Could someone clue me in please? Why is (!(array[i] in result)) not evaluating to true the first time but is the second time? Answer: p in o means "does object o have property named p" (or in case of arrays, equivalently "does array o have an index p"), not "does array o have a value p". [1, 2, 3] has indices 0, 1 and 2 - no 3.

The return value of p new_array on line 7 is [] because the last evaluated expression in the block returns the value of nil, which gives the block a “falsey” return value.

Comments
  • Great question. These are always such tough things to figure out in languages and have such satisfying "ah ha!" moments when you figure out what's happening :)
  • To get the expected result use numbers.map {|number| number < 2 }.uniq
  • What is p in the block doing?
  • The true/false would come from the map. I do understand what uniq returns. I am not understanding why if I swap uniq and map why uniq will do it's thing and pass the result forward to map but the opposite is not true.
  • Enumerable#map returns an Enumerator instance, not an Enumerable. This is usually a result of call to Object#enum_for: def my_each; return enum_for(:each) unless block_given?; ... end.
  • Maybe add a little context to this answer. You are not wrong, although the result will differ for the proposed intention, you have just not explained anything right now. Remember this is a teachable moment for the OP so offer some insight
  • This makes me wonder why uniq can be pass forward values but map will not?
  • @JustinDuncan Please, read documentation for uniq method ruby-doc.org/core-2.6.1/Array.html#method-i-uniq ruby numbers.map.uniq {|number| p number < 2 } equivalent to ruby numbers.uniq {|number| p number < 2 }
  • @AlekseiMatiushkin you got there first