Kevin February 2016

Return unique values of an array without using `uniq`

For a challenge, I'm trying to return the unique values of an array without using uniq. This is what I have so far, which doesn't work:

def unique
   unique_arr = []
   input_arr.each do |word|
     if word != unique_arr.last
       unique_arr.push word
     end
   end
   puts unique_arr
end
input = gets.chomp
input_arr = input.split.sort
input_arr.unique

My reasoning here was that if I sorted the array first before I iterated through it with each, I could push it to unique_arr without repetition being a possibility considering if it's a duplicate, the last value pushed would match it.

Am I tackling this the wrong way?

Answers


G.B February 2016

That's so easy if you see it this way:

a = [1,1,2,3,4]
h = Hash.new
a.each{|q| h[q] = q}
h.values

and this will return:

[1, 2, 3, 4]


sawa February 2016

Yes, you are making at least two mistakes.

  1. If you want to call it as input_arr.unique with input_arr being an array, then you have to define the method on Array. You have input_arr within your method body, which comes from nowhere.
  2. puts in the last line of your code outputs to the terminal, but makes the method return nil, which makes it behave differently from uniq.

It can be fixed as:

class Array
  def unique
    unique_arr = []
    each do |word|
      unique_arr.push(word) unless unique_arr.last == word
    end
    unique_arr
  end
end


Dave Schweisguth February 2016

Here's a concise way to do it that doesn't explicitly use functionality from another class but probably otherwise misses the point of the challenge:

class Array
  def unique
    group_by(&:itself).keys
  end
end


spickermann February 2016

A unique array? That sounds like a Set to me:

require 'set'

Set.new([1,2,3,2,3,4]).to_a
#=> [1,2,3,4]


Lukas Baliak February 2016

I try this three options. Just for challenge

class Array
  def unique
    self.each_with_object({}) { |k, h| h[k] = k }.keys
  end

  def unique2
    self.each_with_object([]) { |k, a| a << k unless a.include?(k) }
  end

  def unique3
    arr = []
    self.map { |k| arr << k unless arr.include?(k) }
    arr
  end
end


Wand Maker February 2016

Here is one more way to do this:

uniques = a.each.with_object([]) {|el, arr| arr << el if not arr.include?(el)}

Post Status

Asked in February 2016
Viewed 1,121 times
Voted 9
Answered 6 times

Search




Leave an answer