簡體   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