【问题标题】:Compare arrays of objects and return new array of objects that are not in one of the arrays比较对象数组并返回不在其中一个数组中的新对象数组
【发布时间】:2020-08-17 09:54:26
【问题描述】:

我一直无法弄清楚如何让它发挥作用。

基本上,我有两个数组。这些数组将包含对象。

第一个数组,是一个包含用户喜爱电台的对象数组。

第二个数组,是一个包含需要移除的站点的对象数组。

我想比较第一个和第二个数组,并返回一个新数组,其中包含不在删除站数组中的站...

例如...

const favourites = [{ station_name: 'Kyle of Lochalsh', crs_code: 'KYL' }, { station_name: 'Connel Ferry', crs_code: 'CON' }, { station_name: 'Oban', crs_code: 'OBN' }]

const toBeRemoved = [{ station_name: 'Kyle of Lochalsh', crs_code: 'KYL' }]

然后我希望返回一个包含其他 2 个站的数组...

我花了几个小时试图弄清楚如何去做,但似乎没有用!

TIA

【问题讨论】:

  • 请分享您一直在使用的代码。请注意,在 Javascript 中,对象标识取决于它们的内存地址,而不是它们的属性值。

标签: javascript arrays


【解决方案1】:

以下代码演示了具有相同属性的两个对象可能不相等:

const ob_1={color:'black', size:'big'},  
      ob_2={color:'black', size:'big'};  
console.log(ob_1==ob_2); // false  

所以我们需要经常进行深度比较:

const favourites = [
  { station_name: 'Kyle of Lochalsh', crs_code: 'KYL' },
  { station_name: 'Connel Ferry', crs_code: 'CON' },
  { station_name: 'Oban', crs_code: 'OBN' }
];
const toBeRemoved = [
  { station_name: 'Kyle of Lochalsh', crs_code: 'KYL' }
];

console.log(

  // Array.filter applies our custom function to each item in the 
  // `favourites` array and returns a new (smaller) array containing
  // all items for which our custom function returns true
  favourites.filter(

    // Our custom function (using "arrow function" syntax) takes
    // a station object and uses `Array.some` to compare it to each 
    // item in the `toBeRemoved` array. Our custom function returns
    // true if the current station is not in `toBeRemoved`.
    (station) =>

      // Array.some takes another custom function which is applied
      // to each item in `toBeRemoved`, returning true if this 
      // custom function returns true for at least one item

      !toBeRemoved.some(
        // This custom function takes a station object (called `st`)
        // and "deeply" compares each property against the same 
        // property in the current station of the `favorites` 
        // array, returning true if both properties match

        (st) =>
          st.station_name == station.station_name &&
          st.crs_code == station.crs_code
      )
  )
);

【讨论】:

  • 如果 OP 在不了解发生了什么的情况下复制粘贴它,这个答案应该可以工作——但如果它解释了为什么这个解决方案有效以及为什么我们可能更喜欢它,那将是一个更好的答案其他可能的解决方案。
  • 哦,是的...下面的代码演示了不同的对象可能具有相同的属性:const ob_1={color:'black', size:'big'}, ob_2={color:'black', size:'big'}; console.log(ob_1==ob_2) //false 所以我们需要始终进行深度比较...
【解决方案2】:

您只需要像这样根据第二个过滤第一个 -:

const favouriteArrayMap = favourites.reduce((acc, item) => ({...acc, [item.crs_code]: 1}), {});
const finalArr = favourites.filter(item => !favouriteArrayMap[item.crs_code]);

这是比使用.includes.some 更优化的解决方案,并且将以线性复杂度运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-02
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 2013-05-17
    • 1970-01-01
    相关资源
    最近更新 更多