Skip to content

Commit

Permalink
✨ ZMPOP
Browse files Browse the repository at this point in the history
  • Loading branch information
JerrodCarpenter committed May 2, 2023
1 parent a1e9c17 commit 4f9eade
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
36 changes: 36 additions & 0 deletions lib/redis/commands/sorted_sets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,42 @@ def zpopmin(key, count = nil)
end
end

# Removes and returns up to count members with scores in the sorted set stored at key.
#
# @example Popping a member
# redis.zmpop('zset')
# #=> ['zset', ['a', 1.0]]
# @example With count option
# redis.zmpop('zset', count: 2)
# #=> ['zset', [['a', 1.0], ['b', 2.0]]
#
# @params key [String, Array<String>] one or more keys with sorted sets
# @params modifier [String]
# - when `"MIN"` - the elements popped are those with lowest scores
# - when `"MAX"` - the elements popped are those with the highest scores
# @params count [Integer] a number of members to pop
#
# @return [Array<String, Array<String, Float>>] list of popped elements and scores
def zmpop(*keys, modifier: "MIN", count: 1)
raise ArgumentError, "Pick either MIN or MAX" unless modifier == "MIN" || modifier == "MAX"

args = [:zmpop, keys.size, *keys, modifier]

if count
args << "COUNT"
args << Integer(count)
end

send_command(args) do |response|
response&.map do |entry|
case entry
when String then entry
when Array then entry.map { |pair| FloatifyPairs.call(pair) }.flatten(1)
end
end
end
end

# Removes and returns up to count members with the highest scores in the sorted set stored at keys,
# or block until one is available.
#
Expand Down
14 changes: 14 additions & 0 deletions test/lint/sorted_sets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,20 @@ def test_zpopmin
assert_equal [['d', 3.0]], r.zrange('foo', 0, -1, with_scores: true)
end

def test_zmpop
target_version('7.0') do
assert_nil r.zmpop('foo')

r.zadd('foo', %w[0 a 1 b 2 c 3 d])
assert_equal ['foo', [['a', 0.0]]], r.zmpop('foo')
assert_equal ['foo', [['b', 1.0], ['c', 2.0], ['d', 3.0]]], r.zmpop('foo', count: 4)

r.zadd('foo', %w[0 a 1 b 2 c 3 d])
r.zadd('foo2', %w[0 a 1 b 2 c 3 d])
assert_equal ['foo', [['d', 3.0]]], r.zmpop('foo', 'foo2', modifier: "MAX")
end
end

def test_zremrangebylex
r.zadd('foo', %w[0 a 0 b 0 c 0 d 0 e 0 f 0 g])
assert_equal 5, r.zremrangebylex('foo', '(b', '[g')
Expand Down

0 comments on commit 4f9eade

Please sign in to comment.