我真的很喜欢带redis的node.js,但我无法征服异步性。我再次拥有传统数据库和语言中的简单任务。我的问题更多的是关于在异步数据库获取中完成控制流和逻辑,而不是我的问题解决方法是否是最优的。
这就是我要做的事情:我的redis键由单词构成,让我们只说car
和card
。现在,给定一个输入字符串,我想知道最长子字符串是什么,匹配redis中的键。我只需要检查从给定字符串的位置0开始的子字符串,因此复杂性很低。
示例:cardinal
中包含密钥card
,还有car
,但card
更长。 Cape
与任一键都不匹配。
我的方法是:从整个字符串开始,检查它是否与键匹配。如果是,请返回该密钥。否则,使用字符串减去最后一个字符重复相同的过程。
我该如何完成这项任务?欢迎采用不同的方法。
我对async
库有点了解,看起来waterfall
最适合我正在做的事情。但是,似乎我需要键入string.length,string.length-1等所有函数,直到最后一个单字符。我正在寻找的是一个休息的for循环的良好替代。
下面我用输入测试我假设总是3个字符或更多(因为它已经很难看了,更多的嵌套似乎没有用于测试)。它有效,carde
生成card
,care
- > car
。废话给出了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);
我也尝试过递归,这可能是最好的方法。 (感谢Timonthy Strimple纠正错误)。
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);
}
}
});
}
}
答案 0 :(得分:4)
我同意递归解决方案可能是最好的。我在研究你的代码之前解决了这个问题(以免影响实验),并得出了一个非常类似的解决方案。使用http://localhost:3000/?word=cardinal
var http = require('http');
var redis = require('redis');
var url = require('url');
var findWord = function(needle, client, callback) {
if (needle.length <= 0) { return callback("Word not found") }
client.keys(needle, function(err, reply) {
if (err) { callback("Word not found"); }
else {
if (reply.length > 0) {
callback(needle);
} else {
findWord(needle.slice(0, -1), client, callback);
}
}
});
};
var server = http.createServer(function(request, response) {
var query = url.parse(request.url, true).query;
var word = query.word || "";
var client = redis.createClient();
findWord(word, client, function(found) {
client.end();
response.writeHead(200, {"Content-Type": "text/plain"});
response.end(found);
});
});
server.listen(3000);