比较两个对象数组,如果对象值相等则删除

问题描述 投票:0回答:4

我已经尝试修改这里的一些类似的解决方案,但我一直陷入困境,我相信我已经解决了部分问题,但主要的警告是:

一些对象有额外的键,这使得我的对象比较逻辑毫无用处。

我正在尝试比较两个对象数组。一个数组是原始数组,另一个数组包含我想要从原始数组中删除的项目。然而,还有一个额外的问题,因为第二个数组包含额外的键,所以我的比较逻辑不起作用。

一个例子会让这更容易,假设我有以下两个数组:

const originalArray = [{id: 1, name: "darnell"}, {id: 2, name: "funboi"}, 
{id: 3, name: "jackson5"}, {id: 4, name: "zelensky"}];

const itemsToBeRemoved = [{id: 2, name: "funboi", extraProperty: "something"}, 
{id: 4, name: "zelensky", extraProperty: "somethingelse"}];

运行逻辑后,我的最终输出应该是这个数组:

[{id: 1, name: "darnell"}, {id: 3, name: "jackson5"}]

这是我当前的代码/逻辑,它比较但不处理额外的键。我应该如何处理这个问题?预先感谢您。

const prepareArray = (arr) => {
  return arr.map((el) => {
    if (typeof el === "object" && el !== null) {
      return JSON.stringify(el);
    } else {
      return el;
    }
  });
};

const convertJSON = (arr) => {
  return arr.map((el) => {
    return JSON.parse(el);
  });
};

const compareArrays = (arr1, arr2) => {
  const currentArray = [...prepareArray(arr1)];
  const deletedItems = [...prepareArray(arr2)];
  const compared = currentArray.filter((el) => deletedItems.indexOf(el) === -1);
  return convertJSON(compared);
};
javascript arrays function object javascript-objects
4个回答
5
投票

使用

filter
some
怎么样?您可以使用
&&
扩展所选属性的过滤条件。

const originalArray = [
  { id: 1, name: 'darnell' },
  { id: 2, name: 'funboi' },
  { id: 3, name: 'jackson5' },
  { id: 4, name: 'zelensky' },
];
const itemsToBeRemoved = [
  { id: 2, name: 'funboi', extraProperty: 'something' },
  { id: 4, name: 'zelensky', extraProperty: 'somethingelse' },
];
console.log(
  originalArray.filter(item => !itemsToBeRemoved.some(itemToBeRemoved => itemToBeRemoved.id === item.id))
)

或者你也可以概括它。

const originalArray = [
  { id: 1, name: 'darnell' },
  { id: 2, name: 'funboi' },
  { id: 3, name: 'jackson5' },
  { id: 4, name: 'zelensky' },
];
const itemsToBeRemoved = [
  { id: 2, name: 'funboi', extraProperty: 'something' },
  { id: 4, name: 'zelensky', extraProperty: 'somethingelse' },
];
function filterIfSubset(originalArray, itemsToBeRemoved) {
  const filteredArray = [];
  for (let i = 0; i < originalArray.length; i++) {
    let isSubset = false;
    for (let j = 0; j < itemsToBeRemoved.length; j++) {
      // check if whole object is a subset of the object in itemsToBeRemoved
      if (Object.keys(originalArray[i]).every(key => originalArray[i][key] === itemsToBeRemoved[j][key])) {
        isSubset = true;
      }
    }
    if (!isSubset) {
      filteredArray.push(originalArray[i]);
    }
  }
  return filteredArray;
}
console.log(filterIfSubset(originalArray, itemsToBeRemoved));

第二种方法的另一个更简单的变体:

const originalArray = [
  { id: 1, name: 'darnell' },
  { id: 2, name: 'funboi' },
  { id: 3, name: 'jackson5' },
  { id: 4, name: 'zelensky' },
];
const itemsToBeRemoved = [
  { id: 2, name: 'funboi', extraProperty: 'something' },
  { id: 4, name: 'zelensky', extraProperty: 'somethingelse' },
];
const removeSubsetObjectsIfExists = (originalArray, itemsToBeRemoved) => {
  return originalArray.filter(item => {
    const isSubset = itemsToBeRemoved.some(itemToBeRemoved => {
      return Object.keys(item).every(key => {
        return item[key] === itemToBeRemoved[key];
      });
    });
    return !isSubset;
  });
}
console.log(removeSubsetObjectsIfExists(originalArray, itemsToBeRemoved));


1
投票

下面的示例是一个可重用的函数,第三个参数是比较两个数组中的值的键。

详情已在示例中注释

const arr=[{id:1,name:"darnell"},{id:2,name:"funboi"},{id:3,name:"jackson5"},{id:4,name:"zelensky"}],del=[{id:2,name:"funboi",extraProperty:"something"},{id:4,name:"zelensky",extraProperty:"somethingelse"}];

/** Compare arrayA vs. delArray by a given key's value.
--- ex. key = 'id'
**/
function deleteByKey(arrayA, delArray, key) {
  /* Get an array of only the values of the given key from delArray
  --- ex. delList = [1, 2, 3, 4]
  */
  const delList = delArray.map(obj => obj[key]);
  
  /* On every object of arrayA compare delList values vs 
 current object's key's value
  --- ex. current obj[id] = 2
  --- [1, 2, 3, 4].includes(obj[id])
  Any match returns an empty array and non-matches are returned 
  in it's own array.
  --- ex. ? [] : [obj]
  The final return is a flattened array of the non-matching objects
  */
  return arrayA.flatMap(obj => delList.includes(obj[key]) ? [] : [obj]);  
};

console.log(deleteByKey(arr, del, 'id'));


0
投票

let ff = [{ id: 1, name: 'darnell' }, { id: 2, name: 'funboi' }, { id: 3, 名称: 'jackson5' }, { id: 4, name: '泽连斯基' }]

let cc = [{ id: 2, name: 'funboi', extraProperty: 'something' },
 { id: 4, name: 'zelensky', extraProperty: 'somethingelse' }]
 let ar = []
 let out = []

const result =  ff.filter(function(i){
ar.push(i.id)
cc.forEach(function(k){
  out.push(k.id)
})
if(!out.includes(i.id)){
  // console.log(i.id, i)
  return i
 }
})
console.log(result)

0
投票

您可以使用

similar-js
npm 包来比较两个也具有数组的对象。

© www.soinside.com 2019 - 2024. All rights reserved.