How can I pop an element from a Set in Ruby?

In Python I can do a_set.pop() and I remove an element from the set and catch it in a variable. Is there a way to do the same thing with a set in Ruby?

Upvotes: 7

Views: 3584

Answers (4)

Michael Mior
Michael Mior

Reputation: 28762

If you just want any element of the set returned, this will work.

class Set
  def pop
    popped = first
    delete(first)
    popped
  end
end

Upvotes: 1

iNulty
iNulty

Reputation: 923

pop should always mean popped off the stack. A stack is last-in-first-out. That to me would mean that

1) The set should be ordered 2) The last element added is the one that gets popped

My implementation would be:

class Set
  def pop
    element = to_a.last
    delete(element)
    element
  end
end

Upvotes: 1

dwenzel
dwenzel

Reputation: 1434

The best way to research a question like this is to look at the docs. A Google search for 'ruby set' will help you to find the doc for the ruby Set class. You can then review all of the available instance methods.

As you can see, a Set is "a collection of unordered values with no duplicates." Since it's unordered, it's not designed to get values at particular locations within the set, including the last value.

You could convert to an array using #to_a and then use #pop on the array, but since the order of a Set is not guaranteed, you might not end up with the value you're expecting.

Edit: Interestingly, pop in Python deletes and returns "an arbitrary element." I see now that that's what you were looking for. While this is not available as a built-in method in a Ruby set, I suppose you could implement it using Array#sample, which grabs a random element from an array, and then delete it from the Set:

class Set
  def pop
    el = self.to_a.sample
    self.delete(el)
    el
  end
end

Upvotes: 3

pangpang
pangpang

Reputation: 8821

Ruby Set haven't pop method, but you can do like this:

class Set
  def pop
    temp = self.to_a.pop
    self.delete(temp)
    temp
  end
end

s1 = Set.new [1, 2]
=> #<Set: {1, 2}>
s1.pop
=> 2
s1
=> #<Set: {1}>

Upvotes: 1

Related Questions