使用另一个数组从数组中删除条目
Remove entry from array using another array
不知道该怎么做,非常感谢您的帮助
说我有 :
const array1 = [1, 1, 2, 3, 4];
const array2 = [1, 2];
期望的输出
const result = [1, 3, 4];
我想比较 array1
和 array2
,并且对于 array2
中的每个条目,从 array1
中删除等效项。因此,如果我在 array1
中有 3 of 1 和在 array2
中有 1 of 1,则结果数组应该有 2 of 1.
从事同时具有 jquery 和 underscore.js 的项目,如果这样可以使事情变得更容易的话。
您可以尝试以下方法。循环遍历array1,检查array1上是否存在array2的元素,拼接出来
const array1 = [1, 1, 2, 3, 4];
const array2 = [1, 2];
for(i=0;i<=array1.length;i++){
for(j=0;j<array2.length;j++){
if(array2[j] == array1[i]){
array1.splice(i,1);
}
}
}
console.log(array1);
var array1 = [1, 1, 2, 3, 4],
array2 = [1, 2],
result = array1.slice(0);
array2.forEach(function(element) {
var index = result.indexOf(element)
if (index >= 0) {
result.splice(index, 1)
}
})
console.log(result)
这 运行 相当不错。我认为它是线性时间而不是 N*N
function diffOnlyOncePerElementInstance(a1, a2) {
const max = Math.max(a1.length, a2.length);
const map = {};
for (let i = 0; i < max; i++) {
const valueA = a1[i];
const valueB = a2[i];
if (i < a1.length) {
if (!Number.isInteger(map[valueA])) {
map[valueA] = 0;
}
map[valueA]++;
}
if (i < a2.length) {
if (!Number.isInteger(map[valueB])) {
map[valueB] = 0;
}
map[valueB]--
}
}
return Object.keys(map)
.map(key => new Array(Math.abs(map[key])).fill(key)) // regenerate remaining count
.reduce((a,b) => a.concat(b), []); // flatten
}
如果您要使用大型数组,此解决方案的性能会非常好。首先将 array1
转换为 Map
以加快查找速度。然后通过 array2
并从 map
中减去以表示应删除该元素。然后最后 运行 通过你的 map
并添加值大于 0
的键
const array1 = [1, 1, 2, 3, 4];
const array2 = [1, 2];
const obj = array1.reduce((acc, cv) => {
if (acc.has(cv)) acc.set(cv, acc.get(cv) + 1);
else acc.set(cv, 1);
return acc;
}, new Map());
array2.forEach(i => {
if (obj.has(i)) obj.set(i, obj.get(i) - 1);
});
const res = [];
obj.forEach((v, k) => { if (v) res.push(k); });
console.log(res)
不确定在现代 JS 中执行此操作的最有效方法,我很漂亮 old-school,所以这是一个 old-school 解决方案:
var array1 = [1, 1, 2, 3, 4];
var array2 = [1, 2];
// Note this method is destructive
Array.prototype.removeFirstValueMatch = function(ar)
{
var indexesToRemoveAr = [];
var indexesToRemoveOb = {};
for(var i=0, j; i<ar.length; i++)
{
for(j=0; j<this.length; j++)
{
if(this[j] == ar[i] && !indexesToRemoveOb.hasOwnProperty(j) )
{
indexesToRemoveOb[j] = indexesToRemoveAr.length;
indexesToRemoveAr.push(j);
break;
}
}
}
var descending = indexesToRemoveAr.sort().reverse();
for(i=0; i<descending.length; i++)
{
this.splice(descending[i],1);
}
return this;
};
// Destructive
console.log(array1.removeFirstValueMatch(array2));//[1, 3, 4]
console.log(array1.removeFirstValueMatch(array2));//[3, 4]
// Non-Destructive
var array1 = [1, 1, 2, 3, 4];
console.log(array1.slice(0).removeFirstValueMatch(array2));//[1, 3, 4]
console.log(array1.slice(0).removeFirstValueMatch(array2));//[1, 3, 4]
IMO 使用 array2
作为对象而不是数组将是最高效的方式。
在这里,在第一次找到键时,我们更改了对象中的值,因此我们不会根据需要在输出中再次过滤该值。
const array1 = [1, 1, 2, 3, 4];
const array2 = Object.create(null,{
1:{writable: true,value:false},
2:{writable: true,value:false}
})
let op = array1.filter(e=> {
if(array2[e] === false){
array2[e] = true
return false
}
return true
})
console.log(op)
旁注:- 使用 object.create
我们正在创建一个没有原型的对象,因此它不会在完整的原型链中搜索值。
您可以 Map
计算要删除的项目数。
const
array1 = [1, 1, 2, 3, 4],
array2 = [1, 2],
remove = array2.reduce((m, v) => m.set(v, (m.get(v) || 0) + 1), new Map),
result = array1.filter(v => !remove.get(v) || !remove.set(v, remove.get() - 1));
console.log(...result);
不知道该怎么做,非常感谢您的帮助
说我有 :
const array1 = [1, 1, 2, 3, 4];
const array2 = [1, 2];
期望的输出
const result = [1, 3, 4];
我想比较 array1
和 array2
,并且对于 array2
中的每个条目,从 array1
中删除等效项。因此,如果我在 array1
中有 3 of 1 和在 array2
中有 1 of 1,则结果数组应该有 2 of 1.
从事同时具有 jquery 和 underscore.js 的项目,如果这样可以使事情变得更容易的话。
您可以尝试以下方法。循环遍历array1,检查array1上是否存在array2的元素,拼接出来
const array1 = [1, 1, 2, 3, 4];
const array2 = [1, 2];
for(i=0;i<=array1.length;i++){
for(j=0;j<array2.length;j++){
if(array2[j] == array1[i]){
array1.splice(i,1);
}
}
}
console.log(array1);
var array1 = [1, 1, 2, 3, 4],
array2 = [1, 2],
result = array1.slice(0);
array2.forEach(function(element) {
var index = result.indexOf(element)
if (index >= 0) {
result.splice(index, 1)
}
})
console.log(result)
这 运行 相当不错。我认为它是线性时间而不是 N*N
function diffOnlyOncePerElementInstance(a1, a2) {
const max = Math.max(a1.length, a2.length);
const map = {};
for (let i = 0; i < max; i++) {
const valueA = a1[i];
const valueB = a2[i];
if (i < a1.length) {
if (!Number.isInteger(map[valueA])) {
map[valueA] = 0;
}
map[valueA]++;
}
if (i < a2.length) {
if (!Number.isInteger(map[valueB])) {
map[valueB] = 0;
}
map[valueB]--
}
}
return Object.keys(map)
.map(key => new Array(Math.abs(map[key])).fill(key)) // regenerate remaining count
.reduce((a,b) => a.concat(b), []); // flatten
}
如果您要使用大型数组,此解决方案的性能会非常好。首先将 array1
转换为 Map
以加快查找速度。然后通过 array2
并从 map
中减去以表示应删除该元素。然后最后 运行 通过你的 map
并添加值大于 0
const array1 = [1, 1, 2, 3, 4];
const array2 = [1, 2];
const obj = array1.reduce((acc, cv) => {
if (acc.has(cv)) acc.set(cv, acc.get(cv) + 1);
else acc.set(cv, 1);
return acc;
}, new Map());
array2.forEach(i => {
if (obj.has(i)) obj.set(i, obj.get(i) - 1);
});
const res = [];
obj.forEach((v, k) => { if (v) res.push(k); });
console.log(res)
不确定在现代 JS 中执行此操作的最有效方法,我很漂亮 old-school,所以这是一个 old-school 解决方案:
var array1 = [1, 1, 2, 3, 4];
var array2 = [1, 2];
// Note this method is destructive
Array.prototype.removeFirstValueMatch = function(ar)
{
var indexesToRemoveAr = [];
var indexesToRemoveOb = {};
for(var i=0, j; i<ar.length; i++)
{
for(j=0; j<this.length; j++)
{
if(this[j] == ar[i] && !indexesToRemoveOb.hasOwnProperty(j) )
{
indexesToRemoveOb[j] = indexesToRemoveAr.length;
indexesToRemoveAr.push(j);
break;
}
}
}
var descending = indexesToRemoveAr.sort().reverse();
for(i=0; i<descending.length; i++)
{
this.splice(descending[i],1);
}
return this;
};
// Destructive
console.log(array1.removeFirstValueMatch(array2));//[1, 3, 4]
console.log(array1.removeFirstValueMatch(array2));//[3, 4]
// Non-Destructive
var array1 = [1, 1, 2, 3, 4];
console.log(array1.slice(0).removeFirstValueMatch(array2));//[1, 3, 4]
console.log(array1.slice(0).removeFirstValueMatch(array2));//[1, 3, 4]
IMO 使用 array2
作为对象而不是数组将是最高效的方式。
在这里,在第一次找到键时,我们更改了对象中的值,因此我们不会根据需要在输出中再次过滤该值。
const array1 = [1, 1, 2, 3, 4];
const array2 = Object.create(null,{
1:{writable: true,value:false},
2:{writable: true,value:false}
})
let op = array1.filter(e=> {
if(array2[e] === false){
array2[e] = true
return false
}
return true
})
console.log(op)
旁注:- 使用 object.create
我们正在创建一个没有原型的对象,因此它不会在完整的原型链中搜索值。
您可以 Map
计算要删除的项目数。
const
array1 = [1, 1, 2, 3, 4],
array2 = [1, 2],
remove = array2.reduce((m, v) => m.set(v, (m.get(v) || 0) + 1), new Map),
result = array1.filter(v => !remove.get(v) || !remove.set(v, remove.get() - 1));
console.log(...result);