CBa*_*arr 54 javascript arrays jquery
我有多个带有字符串值的数组,我想比较它们,只保留所有数组之间相同的匹配结果.
鉴于此示例代码:
var arr1 = ['apple', 'orange', 'banana', 'pear', 'fish', 'pancake', 'taco', 'pizza'];
var arr2 = ['taco', 'fish', 'apple', 'pizza'];
var arr3 = ['banana', 'pizza', 'fish', 'apple'];
Run Code Online (Sandbox Code Playgroud)
我想生成以下包含所有给定数组的匹配的数组:
['apple', 'fish', 'pizza']
Run Code Online (Sandbox Code Playgroud)
我知道我可以将所有数组组合在一起,var newArr = arr1.concat(arr2, arr3);但只需给我一个包含所有数组的数组,再加上重复数组.这可以轻松完成,而不需要像underscore.js这样的库的开销吗?
(太好了,现在我也饿了!)
编辑我想我应该提到可能有一个未知数量的数组,我只是以3为例.
小智 83
var result = arrays.shift().filter(function(v) {
return arrays.every(function(a) {
return a.indexOf(v) !== -1;
});
});
Run Code Online (Sandbox Code Playgroud)
演示: http : //jsfiddle.net/nWjcp/2/
您可以先对外部数组进行排序,以便在开始时获得最短的数组...
arrays.sort(function(a, b) {
return a.length - b.length;
});
Run Code Online (Sandbox Code Playgroud)
为了完整起见,这里有一个处理数组中重复项的解决方案.它使用.reduce()而不是.filter()......
var result = arrays.shift().reduce(function(res, v) {
if (res.indexOf(v) === -1 && arrays.every(function(a) {
return a.indexOf(v) !== -1;
})) res.push(v);
return res;
}, []);
Run Code Online (Sandbox Code Playgroud)
演示: http : //jsfiddle.net/nWjcp/4/
jfr*_*d00 13
现在,您已经在问题中添加了不确定数量的数组,这是另一种方法,它将每个项目的计数收集到一个对象中,然后整理具有最大计数的项目.
这种方法的优点:
这是代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
工作演示: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>";Run Code Online (Sandbox Code Playgroud)
Red*_*edu 12
假设有一组数组我们想要找到它们的交集,那么最简单的单线程方法就可以了
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>");Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
38749 次 |
| 最近记录: |