我有一个id数组和一个JavaScript对象数组。我需要使用Node JS中的数组中的值过滤/搜索JavaScript对象数组。
例如
var id = [1,2,3];
var fullData = [
{id:1, name: "test1"}
,{id:2, name: "test2"}
,{id:3, name: "test3"}
,{id:4, name: "test4"}
,{id:5, name: "test5"}
];
使用上述数据,结果我需要:
var result = [
{id:1, name: "test1"}
,{id:2, name: "test2"}
,{id:3, name: "test3"}
];
我知道我可以遍历两者并检查匹配的ID。但这是实现它的唯一方法还是有更简单和资源友好的解决方案。
将要比较的数据量约为30-40k行。
答案 0 :(得分:2)
var result = fullData.filter(function(item){ // Filter fulldata on...
return id.indexOf(item.id) !== -1; // Whether or not the current item's `id`
}); // is found in the `id` array.
请注意,此filter
功能在IE 8或更低版本上不可用,但the MDN has a polyfill available。
答案 1 :(得分:1)
只要您开始使用未排序的所有可能对象的数组,就无法通过它进行迭代。 @Cerbrus'的回答是一种很好的方法,{{1但是你也可以使用循环。
但是你真的需要从未排序的所有可能对象数组开始吗?
例如,可以在它们进入阵列之前过滤掉这些对象吗?也许你可以在第一次构建数组时应用你的测试,以便那些失败的对象测试从未成为它的一部分。这对资源更友好,如果它对你的特定应用程序有意义,那么它甚至可能更简单。
Array.prototype.filter
或者,你可以使用一个跟踪对象是否通过测试的数据结构吗?最简单的方法是,如果你绝对必须使用一个数组,那么最好的方法就是保持一个它的索引。将对象添加到Array时,应用测试:如果对象通过,则将其在Array中的位置放入索引中。然后,当您需要从Array中获取对象时,您可以参考索引:这样,当您不需要首先触摸大多数对象时,不会浪费时间通过Array。如果你有几个不同的测试,那么你可以保留几个不同的索引,每个测试一个。这需要更多的内存,但它可以节省大量的时间。
function insertItemIfPass(theArray, theItem, theTest) {
if (theTest(theItem)) {
theArray.push(theItem);
}
}
// Insert your items by using insertItemIfPass
var i;
for (i = 0; i < theArray.length; i += 1) {
doSomething(theArray[i]);
}
您可以对数组进行排序,以便测试可以短路吗?想象一下您已经设置阵列的设置,以便通过测试的所有内容都是第一个。这样,只要您点击第一个失败的项目,您就会知道所有剩余的项目都将失败。然后你可以马上停止你的循环,因为你知道没有更多的“好”项目。
function insertItem(theArray, theItem, theTest, theIndex) {
theArray.push(theItem);
if (theTest(theItem)) {
theIndex.push(theArray.length - 1);
}
}
// Insert your items using insertItem, which also builds the index
var i;
for (i = 0; i < theIndex.length; i += 1) {
doSomething(theArray[theIndex[i]]);
}
最重要的是,这不是一个语法问题,而是一个算法问题。它听起来不像您当前的数据结构 - 所有可能项目的未排序数组 - 非常适合您的特定问题。根据应用程序需要执行的其他操作,完全使用其他数据结构或使用索引扩充现有结构可能更有意义。无论哪种方式,如果仔细计划,将为您节省一些时间。