查找多个JavaScript数组之间的匹配项我有多个带有字符串值的数组,我想比较它们,只保留所有数组之间相同的匹配结果。鉴于此示例代码:var arr1 = ['apple', 'orange', 'banana', 'pear', 'fish', 'pancake', 'taco', 'pizza'];var arr2 = ['taco', 'fish', 'apple', 'pizza'];var arr3 = ['banana', 'pizza', 'fish', 'apple'];我想生成以下包含所有给定数组的匹配的数组:['apple', 'fish', 'pizza']我知道我可以组合所有数组,var newArr = arr1.concat(arr2, arr3);但只是给我一个包含所有数据的数组,以及重复数据。这可以轻松完成,而不需要像underscore.js这样的库的开销吗?(太好了,现在我也饿了!)编辑我想我应该提到可能有一个未知数量的数组,我只是以3为例。
3 回答
翻翻过去那场雪
TA贡献2065条经验 获得超14个赞
现在,您已经在问题中添加了不确定数量的数组,这是另一种方法,它将每个项目的计数收集到一个对象中,然后整理具有最大计数的项目。
这种方法的优点:
如果数组较大,那么强力搜索选项(由其他答案使用)的速度要快15倍
不需要ES5或ES5垫片(适用于所有浏览器)
完全非破坏性(根本不改变源数据)
处理源数组中的重复项
处理任意数量的输入数组
这是代码:
function containsAll(/* pass all arrays here */) { var output = []; var cntObj = {}; var array, item, cnt; // for each array passed as an argument to the function for (var i = 0; i < arguments.length; i++) { array = arguments[i]; // for each element in the array for (var j = 0; j < array.length; j++) { item = "-" + array[j]; cnt = cntObj[item] || 0; // if cnt is exactly the number of previous arrays, // then increment by one so we count only one per array if (cnt == i) { cntObj[item] = cnt + 1; } } } // now collect all results that are in all arrays for (item in cntObj) { if (cntObj.hasOwnProperty(item) && cntObj[item] === arguments.length) { output.push(item.substring(1)); } } return(output);}
工作演示:http://jsfiddle.net/jfriend00/52mAP/
仅供参考,这不需要ES5,因此可以在没有垫片的情况下在所有浏览器中使用。
在每1000个长15个阵列的性能测试中,这比我在jsperf中使用的搜索方法快了10倍以上:http://jsperf.com/in-all-arrays 。
这是一个使用ES6 Map
并Set
进行重复数据删除和跟踪计数的版本。这样做的优点是数据类型可以保留并且可以是任何东西(它甚至不需要进行自然的字符串转换,数据甚至可以是对象,尽管对象是完全相同的对象,而不是相同的对象属性/值)。
var arrays = [ ['valueOf', 'toString','apple', 'orange', 'banana', 'banana', 'pear', 'fish', 'pancake', 'taco', 'pizza', 1, 2, 999, 888], ['valueOf', 'toString','taco', 'fish', 'fish', 'apple', 'pizza', 1, 999, 777, 999, 1], ['valueOf', 'toString','banana', 'pizza', 'fish', 'apple', 'apple', 1, 2, 999, 666, 555] ]; // subclass for updating cnts class MapCnt extends Map { constructor(iterable) { super(iterable); } cnt(iterable) { // make sure items from the array are unique let set = new Set(iterable); // now update the cnt for each item in the set for (let item of set) { let cnt = this.get(item) || 0; ++cnt; this.set(item, cnt); } }}function containsAll(...allArrays) { let cntObj = new MapCnt(); for (array of allArrays) { cntObj.cnt(array); } // now see how many items have the full cnt let output = []; for (var [item, cnt] of cntObj.entries()) { if (cnt === allArrays.length) { output.push(item); } } return(output);} var result = containsAll.apply(this, arrays);document.body.innerHTML = "<pre>[<br> " + result.join(',<br> ') + "<br>]</pre>";
鸿蒙传说
TA贡献1865条经验 获得超7个赞
假设有一组数组我们想要找到它们的交集,那么最简单的单线程方法就可以了
var arr = [[0,1,2,3,4,5,6,7,8,9],[0,2,4,6,8],[4,5,6,7]], int = arr.reduce((p,c) => p.filter(e => c.includes(e)));document.write("<pre>" + JSON.stringify(int) + "</pre>");
添加回答
举报
0/150
提交
取消