Insert value by index in Redis list
Asked Answered
T

3

12

Is there any way to insert a value into a Redis list by index?

LINSERT can do it by value, but that seems a little backward in that the same value could appear multiple times in the list.

Tephrite answered 11/2, 2014 at 3:25 Comment(0)
S
2

There is a work around which may be a little slow, since all are O(n) operations.

  • Use LIndex to save old value at client.
  • Use LSet to set a tag value which would never inserted in the list on the index.
  • Use LINSERT to insert 2 values(new value, old saved value) after the tag value.
  • Use LRem to delete the tag value.
  • All operations should be in a transaction.
Smithery answered 11/2, 2014 at 6:56 Comment(2)
What is the purpose of the tag value? Could we not achieve the same result by using LINDEX to get the value at the specified index, then use LINSERT to insert the new value before the old value retrieved in step 1?Evaginate
The tag value is intended to be unique - using LINDEX to get the value at the specified index and using that as the pivot for insertion would only work correctly if the value at the target index happens to be unique. As such inserting the tag first makes sense.Carve
R
0

Redis' set is a more appropriate data structure if you need non-repeating elements, or use a sorted set if you to order the elements. Lists are more geared towards pushin' 'n poppin' stuff.

Reathareave answered 11/2, 2014 at 14:6 Comment(1)
That's not the point, a list is needed in many cases which might contain duplicates by intention, however by using LINSERT we cannot indicate BEFORE or AFTER which element we want to insert the new one.Parable
K
0

Developing the yinqiwen answer just to clarify:

Supose that it is intended to insert a value BEFORE the second entry in a list called test.

Start with empty key and fill with data:

127.0.0.1:6379> del test
(integer) 1
127.0.0.1:6379> rpush test "uno"
(integer) 1
127.0.0.1:6379> rpush test "dos"
(integer) 2
127.0.0.1:6379> rpush test "tres"
(integer) 3
127.0.0.1:6379> lrange test 0 -1
1) "uno"
2) "dos"
3) "tres"

Pick data in the position to insert AFTER AND KEEP IT, then replace it with any tag value.

127.0.0.1:6379> lindex test 1
"dos"
127.0.0.1:6379> lset test 1 "my_tag"
OK
127.0.0.1:6379> lrange test 0 -1
1) "uno"
2) "my_tag"
3) "tres"

Insert the old value after the tag.

127.0.0.1:6379> linsert test after my_tag dos
(integer) 4
127.0.0.1:6379> lrange test 0 -1
1) "uno"
2) "my_tag"
3) "dos"
4) "tres"

Insert a value, let's say "insertion" value after the tag

127.0.0.1:6379> linsert test after my_tag insertion
(integer) 5
127.0.0.1:6379> lrange test 0 -1
1) "uno"
2) "my_tag"
3) "insertion"
4) "dos"
5) "tres"

Now, delete the tag and the inserted data will be BEFORE the second value:

127.0.0.1:6379> lrem test 0 my_tag
(integer) 1
127.0.0.1:6379> lrange test 0 -1
1) "uno"
2) "insertion"
3) "dos"
4) "tres"
Kamin answered 11/7, 2022 at 16:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.