是否有搜索算法一直搜索有序列表,直到所有值相等?

时间:2017-04-12 15:41:37

标签: javascript arrays algorithm search

我在JavaScript中有一个带有四个键的对象。每个键都存储一个包含值的数组。它看起来像这样:

{
  one: [...],
  two: [...],
  three: [...],
  four: [...]
}

假设数组中的每个元素都是“Test”类的对象,它有一个名为“complete”的布尔键。

如果我选择从数组3开始,我需要找到第一次出现的Test.complete等于true。如果在数组3中找到该事件,那么假设我从该对象返回该值/其他值。如果那个事件不在数组三中,那么我需要循环遍历四个,一个和两个(按此顺序)。如果我从两个开始,然后循环通过两个,三个,四个和一个(按此顺序)。

假设页面上有一个按钮可将此complete值切换为true,则在某个时刻将不再有false个值,这就是重点我希望停止循环遍历这些Test对象数组。

我知道我可以使用Object.keys(obj)来访问密钥,并且可能有一个函数返回我需要循环的顺序['one', 'two', 'three', 'four'],具体取决于起始数组是什么。

是否存在我可以直接使用或轻松修改此用例的现有搜索算法?我有一个使用递归的实现,但它不会一直循环并保持循环,直到所有Test.complete值都是true

1 个答案:

答案 0 :(得分:1)

首先要做的事情。在数据结构看起来像你想要的那样之前,你不能让你的循环块执行。无论循环次数多少,单个函数调用始终会看到相同的对象。您需要做的是等待下一个tick,然后再次调用该函数,例如使用setTimeout。这也意味着要等待你的功能完成,你需要使用回调或承诺,而不是return

这不起作用:

function waitLoop(obj) {
   while (notDone) {
      ...
   }
   return;
}
waitLoop(myObj); // Blocks until done

相反,你需要接近这样的事情:

var obj = ...;
function waitLoop(callback) { // Note that callback is a function!
   ...
   if (notDone) {
       setTimeout(function () {
           waitLoop(callback);
       }, 0); // setTimeout(..., 0) waits until the next tick
   } else {
       callback();
   }
}

waitLoop(function () {
    // Do something here when waitLoop is done
});

这是Javascript中异步执行的基础知识。您还可以阅读promises,这是一个类似的概念,但界面略有不同。

关于你的问题。看起来你想继续返回第一个找到的值,然后继续循环。这意味着你需要有一个可以在每次迭代时调用的回调,并返回一个值或返回它完成循环。你应该这样做:

var obj = ...;
function waitUntilComplete(callback) {
    let keyOrder = ['three', 'four', 'one', 'two'];
    for (let k = 0; k < keyOrder.length; k++) {
        let a = obj[keyOrder[k]];
        for (let k = 0; k < a.length; k++) {
            let testResult = Test.complete(a[k]));
            if (testResult) {
                // Send back the value and end execution
                callback(false, a[k]);
                setTimeout(function (){
                    waitUntilComplete(callback);
                }, 0);
                return;
            }
        }
    }

    // Complete!
    callback(true, null);
}

waitUntilComplete(function (done, returnValue) {
    if (!done) {
        // Do what you want with returnValue
    } else {
        // Done, Test.complete returns false for all values!
    }
});

还有一件事需要解释:tick。但让我们回到基础。 Javascript是单线程的,带有事件队列。队列开始为空。有时会发生事件:您单击一个具有事件处理程序,setTimeout触发或文档完成加载的按钮。在这些情况下,事件将被推送到事件队列中。你可以看一下&#34;事件&#34;作为一个功能。毕竟,您将事件处理程序注册为函数。该函数被推送到队列中。那又怎样?没有。它只是坐在队列中。运行时不时会唤醒并开始循环遍历事件队列,按顺序调用所有函数。这就是我们所说的tick

这应该可以帮助您理解为什么在等待某些外部事件时无法阻止功能。因为所有事件 - 按钮点击,超时等 - 都被推入队列。但是在当前函数返回之前,运行时不会调用队列中的下一个函数!阻塞函数会阻止其他一切发生。

这就是为什么我们使用回调以及为什么我使用setTimeout来安排下一个循环。上面的waitUntilComplete将循环遍历所有数组一次,然后它将在下一个滴答中安排新的调用。这允许所有其他排队事件发生,以便在循环之间更新obj