作为练习练习,我正在为Redis编写一个lua脚本,它基本上执行JavaScript方法Array#copyWithin()。
引自MDN,
copyWithin()方法复制数组元素的序列 数组到目标开始的位置。副本取自 第二个和第三个参数的索引位置开始和结束。
这是我到目前为止编写的脚本:
local list = redis.call('lrange', KEYS[1], 0, -1)
local target = tonumber(ARGV[1])
local startIndex = tonumber(ARGV[2])
local len = #list
local endIndex = len
--Handle negative startIndex
if startIndex < 0 then
startIndex = len+startIndex
end
--If the third argument is provided, get the endIndex from it
if #ARGV > 2 then
local arg = tonumber(ARGV[3])
if arg >= 0 then
if arg < endIndex then
endIndex = arg
end
else
if len+arg >= 0 then
endIndex = len+arg
else
endIndex = 0
end
end
end
--An array containing the elements which will be copied
local targeted_elements = {}
--Fill elements from the list
for i=1, (endIndex-startIndex+1) do
targeted_elements[i] = list[startIndex+i]
end
--Make sure no additional elements are pushed to the end of array in case of range overflow
local target_end = #targeted_elements
if target + target_end > len then
target_end = len-target
end
--replace all the changed elements of the list in redis
for i=1, target_end do
redis.call('lset', KEYS[1], target+(i-1), targeted_elements[i])
end
在测试期间,第一个测试用例被成功清除:
使用convert [1, 2, 3, 4, 5]
[4, 5, 3, 4, 5]
导入copyWithin(0, 3)
LRANGE MyList 0 -1
> [1, 2, 3, 4, 5]
EVALSHA "sha1 of script" 1 MyList 0 3
(basically the same as `[1, 2, 3, 4, 5].copyWithin(0, 3)`)
> nil
LRANGE MyList 0 -1
> [4, 5, 3, 4, 5]
然而,第二个测试案例并没有那么顺利。
使用convert [1, 2, 3, 4, 5]
[4, 2, 3, 4, 5]
导入copyWithin(0, 3, 4)
LRANGE MyList 0 -1
> [1, 2, 3, 4, 5]
EVALSHA "sha1 of script" 1 MyList 0 3 4
(basically the same as `[1, 2, 3, 4, 5].copyWithin(0, 3, 4)`)
> nil
LRANGE MyList 0 -1
> [4, 5, 3, 4, 5]
经过一些调试后,我发现两个案例中targeted_elements
的值都是{4, 5}
,而案例2中的值{4}
。
循环中有什么可疑之处吗?任何帮助都会很棒。
答案 0 :(得分:2)
我通过修改脚本的以下部分来解决这个问题:
--Fill elements from the list
for i=1, (endIndex-startIndex+1) do
targeted_elements[i] = list[startIndex+i]
end
将其改为:
--Fill elements from the list
for i=1, (endIndex-startIndex) do
targeted_elements[i] = list[startIndex+i]
end
+1
表达式中的for
为数组添加了一个额外的元素。它在第一种情况下起作用,因为所选部分来自3, 5
,因此5-3+1 = 3
表示应选择3
元素。但由于只剩下2
个元素,因此案例仍有效。
对于第二种情况,4-3+1 = 2
,即2
元素,而不是1
。