16 javascript arrays
我知道这个问题,最简单的数组交叉代码,但所有的解决方案都假定数组的数量是两个,这在我的情况下是不可能的.
我在页面上有div包含数组的数据.我想找到所有数组共有的值.我不知道我将提前有多少个div /数组.计算所有数组共有的值的最佳方法是什么?
var array1 = ["Lorem", "ipsum", "dolor"];
var array2 = ["Lorem", "ipsum", "quick", "brown", "foo"];
var array3 = ["Jumps", "Over", "Lazy", "Lorem"];
var array4 = [1337, 420, 666, "Lorem"];
//Result should be ["Lorem"];
Run Code Online (Sandbox Code Playgroud)
我在其他地方使用Underscore.js找到了另一种解决方案.
var arrayOfArrays = [[4234, 2323, 43], [1323, 43, 1313], [23, 34, 43]];
_.intersection.apply(_, arrayOfArrays)
//Result is [43]
Run Code Online (Sandbox Code Playgroud)
我在最后用简单的虚拟数据进行了测试,看起来很有效.但由于某种原因,我正在制作的一些包含简单字符串的数组也自动包含一个附加值,"equals:function":
["Dummy1", "Dummy2", "Dummy3", equals: function]
Run Code Online (Sandbox Code Playgroud)
每当我使用Underscore.js交集方法时,在数组数组中,我总是在开发工具中得到[equals:function],而不是 - 如果"Dummy3"对所有数组都是通用的 - ["Dummy3"].
那么TL; DR是否有另一种适合我的情况的阵列交叉解决方案?任何人都可以解释[equals:function]在这里意味着什么?当我在开发工具中展开项目时,它会生成一个空数组和数组上可用的方法列表(pop,push,shift等),但这些方法都已淡出,而equals:function则突出显示.
Nin*_*olz 14
你可以只使用Array#reduce与Array#filter和Array#includes。
var array1 = ["Lorem", "ipsum", "dolor"],
array2 = ["Lorem", "ipsum", "quick", "brown", "foo"],
array3 = ["Jumps", "Over", "Lazy", "Lorem"],
array4 = [1337, 420, 666, "Lorem"],
data = [array1, array2, array3, array4],
result = data.reduce((a, b) => a.filter(c => b.includes(c)));
console.log(result);Run Code Online (Sandbox Code Playgroud)
我为此写了一个辅助函数:
function intersection() {
var result = [];
var lists;
if(arguments.length === 1) {
lists = arguments[0];
} else {
lists = arguments;
}
for(var i = 0; i < lists.length; i++) {
var currentList = lists[i];
for(var y = 0; y < currentList.length; y++) {
var currentValue = currentList[y];
if(result.indexOf(currentValue) === -1) {
var existsInAll = true;
for(var x = 0; x < lists.length; x++) {
if(lists[x].indexOf(currentValue) === -1) {
existsInAll = false;
break;
}
}
if(existsInAll) {
result.push(currentValue);
}
}
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
intersection(array1, array2, array3, array4); //["Lorem"]
Run Code Online (Sandbox Code Playgroud)
或者像这样:
intersection([array1, array2, array3, array4]); //["Lorem"]
Run Code Online (Sandbox Code Playgroud)
完整代码在这里
更新1
这里使用的实现略小一些filter
如果您喜欢使用一些递归和新的ES2015语法,这可以非常简洁地完成:
const array1 = ["Lorem", "ipsum", "dolor"];
const array2 = ["Lorem", "ipsum", "quick", "brown", "foo"];
const array3 = ["Jumps", "Over", "Lazy", "Lorem"];
const array4 = [1337, 420, 666, "Lorem"];
const arrayOfArrays = [[4234, 2323, 43], [1323, 43, 1313], [23, 34, 43]];
// Filter xs where, for a given x, there exists some y in ys where y === x.
const intersect2 = (xs,ys) => xs.filter(x => ys.some(y => y === x));
// When there is only one array left, return it (the termination condition
// of the recursion). Otherwise first find the intersection of the first
// two arrays (intersect2), then repeat the whole process for that result
// combined with the remaining arrays (intersect). Thus the number of arrays
// passed as arguments to intersect is reduced by one each time, until
// there is only one array remaining.
const intersect = (xs,ys,...rest) => ys === undefined ? xs : intersect(intersect2(xs,ys),...rest);
console.log(intersect(array1, array2, array3, array4));
console.log(intersect(...arrayOfArrays));
// Alternatively, in old money,
var intersect2ES5 = function (xs, ys) {
return xs.filter(function (x) {
return ys.some(function (y) {
return y === x;
});
});
};
// Changed slightly from above, to take a single array of arrays,
// which matches the underscore.js approach in the Q., and is better anyhow.
var intersectES5 = function (zss) {
var xs = zss[0];
var ys = zss[1];
var rest = zss.slice(2);
if (ys === undefined) {
return xs;
}
return intersectES5([intersect2ES5(xs, ys)].concat(rest));
};
console.log(intersectES5([array1, array2, array3, array4]));
console.log(intersectES5(arrayOfArrays));Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7224 次 |
| 最近记录: |