繁体   English   中英

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

[英]Is there a search algorithm that keeps searching an ordered list until all values are equal?

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

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

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

如果选择从数组3开始,则需要找到第一个出现的Test.complete等于true 如果在数组3中找到了这种情况,那么假设我从该对象返回了该值/其他值。 如果不在数组3中出现,那么我需要按顺序遍历四个,一个和两个。 如果我从二开始,那么依次遍历二,三,四和一。

假设页面上有一个按钮可以将这个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
});

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

解决您的问题。 看来您想继续返回第一个找到的值,然后继续循环。 这意味着您需要一个可在每次迭代中调用的回调,并返回一个值或返回已完成循环的值。 您应该执行以下操作:

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将遍历所有数组一次,然后在下一个tick中安排新的调用 这使所有其他排队的事件发生,从而使obj在循环之间有机会更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM