Skip to content

Commit fde7873

Browse files
authored
Merge pull request #1195 from JerrodCarpenter/lmpop
✨ Add LMPOP
2 parents 1f4041a + c787721 commit fde7873

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

lib/redis/commands/lists.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,32 @@ def brpoplpush(source, destination, timeout: 0)
183183
send_blocking_command(command, timeout)
184184
end
185185

186+
# Pops one or more elements from the first non-empty list key from the list
187+
# of provided key names.
188+
#
189+
# @example Popping a element
190+
# redis.lmpop('list')
191+
# #=> ['list', ['a']]
192+
# @example With count option
193+
# redis.lmpop('list', count: 2)
194+
# #=> ['list', ['a', 'b']]
195+
#
196+
# @params key [String, Array<String>] one or more keys with lists
197+
# @params modifier [String]
198+
# - when `"LEFT"` - the elements popped are those from the left of the list
199+
# - when `"RIGHT"` - the elements popped are those from the right of the list
200+
# @params count [Integer] a number of elements to pop
201+
#
202+
# @return [Array<String, Array<String, Float>>] list of popped elements or nil
203+
def lmpop(*keys, modifier: "LEFT", count: nil)
204+
raise ArgumentError, "Pick either LEFT or RIGHT" unless modifier == "LEFT" || modifier == "RIGHT"
205+
206+
args = [:lmpop, keys.size, *keys, modifier]
207+
args << "COUNT" << Integer(count) if count
208+
209+
send_command(args)
210+
end
211+
186212
# Get an element from a list by its index.
187213
#
188214
# @param [String] key

lib/redis/distributed.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,13 @@ def ltrim(key, start, stop)
542542
node_for(key).ltrim(key, start, stop)
543543
end
544544

545+
# Iterate over keys, removing elements from the first non list set found.
546+
def lmpop(*keys, modifier: "LEFT", count: nil)
547+
ensure_same_node(:lmpop, keys) do |node|
548+
node.lmpop(*keys, modifier: modifier, count: count)
549+
end
550+
end
551+
545552
# Get the number of members in a set.
546553
def scard(key)
547554
node_for(key).scard(key)

test/lint/lists.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,5 +202,18 @@ def test_variadic_rpoplpush_expand
202202
redis.rpush('{1}bar', %w[d e f])
203203
assert_equal 'c', redis.rpoplpush('{1}foo', '{1}bar')
204204
end
205+
206+
def test_lmpop
207+
target_version('7.0') do
208+
assert_nil r.lmpop('{1}foo')
209+
210+
r.lpush('{1}foo', %w[a b c d e f g])
211+
assert_equal ['{1}foo', ['g']], r.lmpop('{1}foo')
212+
assert_equal ['{1}foo', ['f', 'e']], r.lmpop('{1}foo', count: 2)
213+
214+
r.lpush('{1}foo2', %w[a b])
215+
assert_equal ['{1}foo', ['a']], r.lmpop('{1}foo', '{1}foo2', modifier: "RIGHT")
216+
end
217+
end
205218
end
206219
end

0 commit comments

Comments
 (0)