I really like node.js with redis, but I can't beat asynchrony. Again I have a simple task in a traditional database and language. My question is more related to the execution of the control flow and logic in the asynchronous selection of the database than the optimal approach to solving problems or not.
Here's what I'm trying to do: I have redis keys made up of words, let's just say carand card. Now, given the input string, I want to know what is the longest substring that matches the key in redis. I only need to check the substrings starting at position 0 of this string, so the complexity is low.
Example: cardinalhas a key in it card, as well car, but cardlonger. Capedoes not match any of the keys.
My approach: start with the whole line and check if it matches the key. If so, return this key. Otherwise, repeat the same process with a line minus the last character.
How can I complete this task? Various approaches are welcome.
I am a little versed in the library asyncand it seems to me that is waterfallbest suited for what I am doing. However, it seems that I need to enter all the functions from string.length, string.length-1, etc. To the last single character. What I'm looking for is a good replacement for a for loop with a break.
Below I test with the input, I assume that it is always 3 characters or more (because it is already ugly and more nesting seems pointless for testing). It works, cardeleads to cardand care→ car. Stupidity gives no match.
var http = require("http");
var redis = require("redis");
http.createServer(function(request, response) {
client = redis.createClient();
word = "carde";
client.keys(word, function(err, reply) {
if(err) { response.end(err); client.end(); }
else {
if(reply.length > 0) {
response.end(word);
client.end();
}
else {
client.keys(word.slice(0,-1), function(err, reply) {
if(err) { response.end(err); client.end(); }
else {
if(reply.length > 0) {
response.end(word.slice(0, -1));
client.end();
}
else {
client.keys(word.slice(0, -2), function(err,reply) {
if(err) { response.end(err); client.end(); }
else {
if(reply.length > 0) {
response.end(word.slice(0, -2));
client.end();
}
else {
response.end("no match");
}
}
});
}
}
});
}
}
});
}).listen(8000);
I also tried recursion, and this might be the best method. (Thanks to Timonthy Strimple for fixing the bug).
http.createServer(function(request, response) {
client = redis.createClient();
recursiveKeys("cardinalsin", client, response);
}).listen(8000);
function recursiveKeys(word, client, response) {
if (word.length == 0) {
response.write("0");
response.end();
client.end();
}
else {
client.keys(word, function(err, reply) {
if(err) {
response.write("0");
response.end();
client.end();
}
else {
if(reply.length > 0) {
response.write(word);
response.end();
client.end();
}
else {
return recursiveKeys(word.slice(0,-1), client, response);
}
}
});
}
}