是否有一种搜索算法可以持续搜索有序列表,直到所有值都相等?



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

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

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

如果我选择从数组 3 开始,我需要找到第一次出现的Test.complete等于true。如果在数组 3 中找到这种情况,假设我从该对象返回该值/其他值。如果该实例不在数组 3 中,则我需要遍历 4、1 和 2(按该顺序)。如果我从两个开始,然后循环遍历两个、三个、四个和一个(按这个顺序)。

假设页面上有一个按钮将此complete值切换为true,在某些时候将不再剩下false值,这就是我想停止循环遍历这些 Test 对象数组的地方。

我知道我可以使用Object.keys(obj)来访问键,并且可能有一个函数,可以根据起始数组的内容返回我需要循环['one', 'two', 'three', 'four']顺序。

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

首先要做的事。在数据结构看起来像您想要的那样之前,您不能让循环块执行。无论您循环多少次,单个函数调用都将始终看到相同的对象。您需要做的是等待下一个即时报价,然后再次调用该函数,例如使用setTimeout。这也意味着要等待函数完成,您需要使用回调或 promise,而不是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中异步执行的基础知识。您还可以阅读承诺,这是一个类似的概念,但界面略有不同。

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

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 触发或文档完成加载。在这些情况下,事件被推送到事件队列中。您可以将"事件"视为一个函数。毕竟,您将事件处理程序注册为函数。该函数被推送到队列中。然后呢?无。它只是坐在队列中。运行时会不时唤醒并开始循环访问事件队列,按顺序调用所有函数。这就是我们所说的tick.

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

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

相关内容

最新更新