2013-07-27 72 views
1

我需要在「數組數組」中找到丟失的數組。我開始發現以下(在計算器上)這個函數:在數組數組中找到丟失的數組

oldarray = ["hi", "ho", "hey"]; 
newarray = ["hi", "hey"]; 

使用findDeselectedItem(newarray, oldarray)將返回[「豪」]:

function findDeselectedItem(CurrentArray, PreviousArray) { 

    var CurrentArrSize = CurrentArray.length; 
    var PreviousArrSize = PreviousArray.length; 
    var deselectedItem = []; 

    // loop through previous array 
    for(var j = 0; j < PreviousArrSize; j++) { 

     // look for same thing in new array 
     if (CurrentArray.indexOf(PreviousArray[j]) == -1) 
     deselectedItem.push(PreviousArray[j]); 

    } 

    return deselectedItem; 
} 

,如果你做了這樣的事情這工作就好了。

然而,我的內容是這樣的:

oldarray = [["James", 17, 1], ["Olivia", 16, 0], ["Liam", 18, 1]]; 
newarray = [["Olivia", 16, 0], ["James", 17, 1]]; 

我如何能適應上述的功能,因此,它返回一個包含「利亞姆」的缺陣。

感謝

+0

在檢查數組數組的情況下,只有當數組的引用相同時,indexOf纔會返回正值或零值。它不會做價值比較 – prasun

回答

2

我會做一個哈希與名稱作爲一個關鍵。這將使查找丟失的內容變得微不足道並且非常快速。然後,您可以通過每次不重建散列來優化方法,但只有在真正有必要時才能重新構建散列。

var oldArray = [["James", 17, 1], ["Olivia", 16, 0], ["Liam", 18, 1]]; 
var newArray = [["Olivia", 16, 0], ["James", 17, 1]]; 

function findDeselectedItems(oldArray, newArray) 
{ 
    var results = []; 

    var hash = {}; 
    for (var i=0; i<newArray.length; i++) {   
     hash[newArray[i].join(',')] = true; 
    } 

    for (var i=0; i<oldArray.length; i++) { 
     if (!hash[oldArray[i].join(',')]) { 
     results.push(oldArray[i]); 
     } 
    } 

    return results; 
} 
+0

非常感謝! :) – jskidd3

+0

要小心,(直到我的編輯被接受)當前算法只檢查每個數組的第一個元素。所以['bob',1,1]將在數組中被「找到」; [['bob',2,2]] – Hashbrown

+0

@Hashbrown爲了克服對名稱的依賴性,algo可以被優化 - hash [newArray [i] .toString()] = true;並且比較會變成if(hash [oldArray [i] .toString()] == null) – prasun

0

我希望這可以幫助你,

function findDeselectedItem(CurrentArray, PreviousArray) { 

    var CurrentArrSize = CurrentArray.length; 
    var PreviousArrSize = PreviousArray.length; 
    var deselectedItem = []; 

    // loop through previous array 
    for(var j = 0; j < PreviousArrSize; j++) { 
     var checkArray = PreviousArrSize[j]; 
     // loop through 2nd array to match both array 

     for(var i = 0; i < CurrentArrSize; i++) { 
      // look for same thing in new array 
      if (CurrentArray[i].indexOf(checkArray) == -1) 
       deselectedItem.push(CurrentArray[i]); 

     } 
    } 
    return deselectedItem; 
} 
+0

嗨,我只是試圖在控制檯中,它並沒有返回丟失的一個。 – jskidd3

0

@KarelG:漂亮和快速的解決方案,但它應該不會是var checkArray = PreviousArr[j];而不是var checkArray = PreviousArrSize[j];

+0

歡迎來到StackOverflow,但這個答案應該是一個評論。此外,KarelG的解決方案無法使用,但您的解決方案並未解決問題。 – jskidd3

+0

嗨喬爾,我會喜歡把我的評論,但設置(我是一個新手,沒有「名譽」> 50),不幸的是不允許它。 : - /到目前爲止,我只能在我自己的帖子上發表評論:-( – cars10m

+0

哦,我的道歉,聽起來像東西應該看看。謝謝無論如何:) – jskidd3

1

問題可能是indexOf使用嚴格的等式。即如果'previous'數組中的項目在'current'數組中不是字面上也不是,它將報告它不在其中。

你將不得不遍歷值自己(而不是使用indexOf),並檢查數組包含的東西是「與」(而不是字面上相同)的陣列。

I.e.如果我沒有足夠的自我解釋,請看看這個;

['bob'] == ['bob']; //false 
//therefore 
[['bob']].indexOf(['bob']); //-1 
+0

我upvoted @NoxNoctis'的答案。這個「答案」更是其背後的原因。他的回答通過評估數組作爲字符串並比較它們來糾正你的問題 – Hashbrown

+0

感謝你的回答,你確實教給我一些關於indexOf的新東西:-) – jskidd3

+0

給我一個upvote然後:) SO有一個很好的系統適合各種答案:P – Hashbrown

0
function findDeselectedItem(CurrentArray, PreviousArray) { 

    var CurrentArrSize = CurrentArray.length; 
    var PreviousArrSize = PreviousArray.length; 
    var deselectedItem = []; 
    var selectedIndices = []; 

    // loop through previous array 
    for(var j = 0; j < PreviousArrSize; j++) { 

    for(k=0; k < CurrentArrSize ; k++){ 
     if (CurrentArray[k].toString() === PreviousArray[j].toString()){ 
      selectedIndices.push(j); 
      break; 
     } 

    } 

} 

    for(var l = 0; l < PreviousArrSize; l++){ 
     if(selectedIndices.indexOf(l) === -1){ 
     deselectedItem.push(PreviousArray[l]); 
     } 
    } 

     return deselectedItem; 
} 
0

我不認爲你可以使用的indexOf來比較兩個數組。你需要更深入的比較。儘管可以用另一種方式編寫代碼,但可以使用數組比較函數並使用Array.some()來過濾元素。這裏有一個例子和一個fiddle;

// Credit http://stackoverflow.com/questions/7837456/comparing-two-arrays-in-javascript 
// attach the .compare method to Array's prototype to call it on any array 
Array.prototype.compare = function (array) { 
    // if the other array is a falsy value, return 
    if (!array) 
     return false; 

    // compare lengths - can save a lot of time 
    if (this.length != array.length) 
     return false; 

    for (var i = 0; i < this.length; i++) { 
     // Check if we have nested arrays 
     if (this[i] instanceof Array && array[i] instanceof Array) { 
      // recurse into the nested arrays 
      if (!this[i].compare(array[i])) 
       return false; 
     } 
     else if (this[i] != array[i]) { 
      // Warning - two different object instances will never be equal: {x:20} != {x:20} 
      return false; 
     } 
    } 
    return true; 
} 

function findDeselectedItem(CurrentArray, PreviousArray) { 

    var CurrentArrSize = CurrentArray.length; 
    var PreviousArrSize = PreviousArray.length; 
    var deselectedItem = []; 

    // loop through previous array 
    for (var j = 0; j < PreviousArrSize; j++) { 
     // look for same thing in new array 
     CurrentArray.some(function (a, idx) { 
      if(PreviousArray[j].compare(a) == false) { 
       deselectedItem.push(PreviousArray[j]); 
       return true; 
      } 
     }); 
    } 

    return deselectedItem; 
    } 

var oldarray =[["James", 17, 1], ["Olivia", 16, 0], ["Liam", 18, 1]]; 
var newarray =[["Olivia", 16, 0], ["James", 17, 1]]; 

console.log(findDeselectedItem(newarray, oldarray));