2013-07-27 64 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));