2017-06-15 2 views
0

Je veux croiser plusieurs ensembles (2 ou plus). Le nombre d'ensembles à croiser est passé en tant que ARGV à partir de la ligne de commande. Comme nombre d'ensembles sont passés à partir de la ligne de commande. Le nombre d'arguments dans la fonction redis.call() est donc incertain.croise plusieurs ensembles avec le script lua en utilisant redis.call ("sinter", ...) commande

Comment puis-je le faire en utilisant la fonction redis.call() dans le script Lua.

Cependant, je l'ai écrit un script qui a algo comme:

  • Accepter le nombre de jeux à recoupée dans les touches [1].
  • Intersection des deux premiers ensembles à l'aide de setIntersected = redis.call(ARGV[1], ARGV[2]).
  • Exécution d'une boucle et utilisation setIntersected = redis.call("sinter", tostring(setIntersected), set[i])
  • Enfin, je devrais obtenir l'ensemble recoupé.

Le code de l'algorithme ci-dessus est:

local noOfArgs = KEYS[1] -- storing the number of arguments that will get passed from cli 

--[[ 
    run a loop noOfArgs time and initialize table elements, since we don't know the number of sets to be intersected so we will use Table (arrays) 
--]] 

local setsTable = {} 

for i = 1, noOfArgs, 1 do 
    setsTable[i] = tostring(ARGV[i]) 
end 


-- now find intersection 
local intersectedVal = redis.call("sinter", setsTable[1], setsTable[2]) -- finding first intersection because atleast we will have two sets 
local new_updated_set = "" 
for i = 3, noOfArgs, 1 do 
    new_updated_set = tostring(intersectedVal) 
    intersectedVal = redis.call("sinter", new_updated_set, setsTable[i]) 
end 

return intersectedVal 

Ce script fonctionne très bien quand je passe deux ensembles à l'aide de la ligne de commande.

EG:

redic-cli --eval scriptfile.lua 2 , points:Above20 points:Above30 

output:- 

1) "playerid:1" 

2) "playerid:2" 

3) "playerid:7" 

points:Above20 et points:Above30 sont des ensembles. Cette fois-ci ne passe pas par la boucle qui commence à partir de i = 3.

Mais quand je passe 3 jeux alors je reçois toujours la sortie comme:

(liste vide ou set)

Il y a donc un problème avec la boucle que j'ai écrite pour trouver l'intersection des ensembles.

Où est-ce que je me trompe? Existe-t-il un moyen optimisé d'utiliser l'intersection de plusieurs ensembles directement?

+0

Y a-t-il une raison particulière pour laquelle vous utilisez un script Lua et pas seulement pour créer une commande SINTER avec plusieurs jeux comme arguments directement? –

Répondre

1

Ce que vous cherchez probablement, c'est l'insaisissable unpack() Lua command, ce qui équivaut à ce qu'on appelle l'opérateur "Splat" dans d'autres langues.

Dans votre code, utilisez les touches suivantes:

local intersectedVal = redis.call("sinter", unpack(setsTable)) 

Cela dit, SINTER est variadique et peut accepter plusieurs clés comme arguments. À moins que votre script ne fasse quelque chose en plus des intesects, vous feriez mieux de l'utiliser à la place.