如果已存在则附加数组或排除项

时间:2018-04-05 12:26:57

标签: javascript lodash

当我在标题中描述我的问题时,我需要实现以下算法:

我得到了一些元素,例如:

let arr1 = [
  {id:1, foo1: '...', foo2: '...'}, 
  {id:2, foo1: '...', foo2: '...'}, 
  {id:3, foo1: '...', foo2: '...'}, 
];

在我的应用程序的某个地方,我得到了另一个数组arr2,它可以包含已经在arr1中的元素。

let arr2 = [
  {id:1, foo1: '...', foo2: '...'}, 
  {id:4, foo1: '...', foo2: '...'}, 
  {id:5, foo1: '...', foo2: '...'}, 
];

如果arr1包含arr2的每个元素,我需要从arr1中排除这些元素。在第二种情况下,arr2包含至少一个也不在arr1中的元素,arr2的所有元素都将附加到arr1。

我尝试了lodash的函数_.xorBy(arr1, arr2, 'id'),它在所有情况下都不起作用。我在lodash的文档中寻找了另外一个函数来满足我的需求,但我没有找到任何东西。

这是我的预期行为(我只使用数字但在实际应用中有这个ID的对象):

  • 给定:arr1 = [1,2,3,4,5]和arr2 = [1,2,3] => resultArr = [4,5]
  • 给定:arr1 = [1,2,3,4,5]和arr2 = [1,2,6] => resultArr = [1,2,3,4,5,6] // 6不同所以追加所有

你能帮助我解决我的问题,或者展示一些优雅的方法吗?谢谢你的建议。

3 个答案:

答案 0 :(得分:3)

如果arr2arr1之间的_.difference()数组长度大于0,则返回_.union()个数组。如果不在_.difference()arr1之间返回arr2

注1: _.difference(arr2, arr1)不等于_.difference(arr1, arr2),因为结果值的顺序和引用由第一个数组确定。

注2:该示例使用基元数组。对于对象数组,请使用By版本 - _.differenceBy()_.unionBy(),并使用属性iteratee简写 - _.differenceBy(arr1, arr2, 'id')



const incEx = (arr1, arr2) => 
  _.difference(arr2, arr1).length > 0 ? 
    _.union(arr1, arr2) 
    : 
    _.difference(arr1, arr2);

console.log(incEx([1,2,3,4,5], [1,2,3]));
console.log(incEx([1,2,3,4,5], [1,2,6]));

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

使用Set的简单Javascript解决方案。

function merge(array1, array2) {
    var ids1 = new Set(array1.map(({ id }) => id)),
        ids2 = new Set(array2.map(({ id }) => id));

    return array2.every(({ id }) => ids1.has(id))
        ? array1.filter(({ id }) => !ids2.has(id))
        : array1.concat(array2.filter(({ id }) => !ids1.has(id)));
}

var array1 = [{ id: 1 }, { id: 2 }, { id: 3 }],
    array2 = [{ id: 1 }, { id: 4 }, { id: 5 }];

console.log(merge(array1, array2));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

  

如果arr1包含arr2的每个元素,我需要排除这些   来自arr1的元素。

检查arr2

中是否包含所有arr1
var hasAllValues = arr2.every( s => !!arr1.find( t => t.id == s.id ) )
如果hasAllValues

中包含所有arr2,则

arr1为真

使用filter删除arr1

中的值
arr1 =  arr1.filter( s => arr2.find( t => t.id == s.id ) );
  

在第二种情况下,arr2包含至少一个元素   也不在arr1中,arr2的所有元素都将附加到arr1。

使用

查找不是arr1的arr2的值
var arr3 =  arr2.filter( s => !!arr1.find( t => t.id == s.id ) );
arr1 = arr1.concat( arr3 );

因此,最终的解决方案是

var hasAllValues = arr2.every( s => !!arr1.find( t => t.id == s.id ) )
if ( hasAllValues )
{
   arr1 =  arr1.filter( s => !arr2.find( t => t.id == s.id ) );
}
else
{
   var arr3 =  arr2.filter( s => !arr1.find( t => t.id == s.id ) );
   arr1 = arr1.concat( arr3 );
}

方案1的演示

&#13;
&#13;
let arr1 = [{
    id: 1
  },
  {
    id: 2
  },
  {
    id: 3
  },
  {
    id: 4
  }
];
let arr2 = [{
    id: 1
  },
  {
    id: 4
  }
];

var hasAllValues = arr2.every(s => !!arr1.find(t => t.id == s.id))
if (hasAllValues) {
  arr1 = arr1.filter(s => !arr2.find(t => t.id == s.id));
} else {
  var arr3 = arr2.filter(s => !arr1.find(t => t.id == s.id));
  //console.log(arr3)
  arr1 = arr1.concat(arr3);
}

console.log(arr1);
&#13;
&#13;
&#13;

方案2的演示

&#13;
&#13;
let arr1 = [{
    id: 1
  },
  {
    id: 2
  },
  {
    id: 3
  }
];
let arr2 = [{
    id: 1
  },
  {
    id: 4
  },
  {
    id: 5
  }
];

var hasAllValues = arr2.every(s => !!arr1.find(t => t.id == s.id))
if (hasAllValues) {
  arr1 = arr1.filter(s => !arr2.find(t => t.id == s.id));
} else {
  var arr3 = arr2.filter(s => !arr1.find(t => t.id == s.id));
  //console.log(arr3)
  arr1 = arr1.concat(arr3);
}

console.log(arr1);
&#13;
&#13;
&#13;

相关问题