3

我真的很想用redis来喜欢node.js,但是我无法克服异步性。我再次拥有传统数据库和语言中的简单任务。我的问题更多是关于在异步数据库获取中完成控制流和逻辑,而不是我的问题解决方法是否最佳。

这就是我想要做的:我有由单词组成的redis键,让我们说carand 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);
          }
        }
      });
  }
}
4

1 回答 1

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);
于 2012-05-02T03:24:52.333 回答