【问题标题】:How to remove duplicates objects in array based on 2 properties?如何根据 2 个属性删除数组中的重复对象?
【发布时间】:2018-03-06 06:04:25
【问题描述】:

我有一个房间对象数组,我目前正在根据它们的 room_rate_type_id 属性从数组中删除重复的对象:

const rooms = [{
    room_rate_type_id: 202,
    price: 200
  },
  {
    room_rate_type_id: 202,
    price: 200
  },
  {
    room_rate_type_id: 202,
    price: 189
  },
  {
    room_rate_type_id: 190,
    price: 200
  }
];

const newRooms = rooms.filter((room, index, array) => {
  const roomRateTypeIds = rooms.map(room => room.room_rate_type_id);
  // Returns the first index found.
  return roomRateTypeIds.indexOf(room.room_rate_type_id) === index;
});

console.log(newRooms);

但是,我还需要确保仅当对象的 room_rate_type_id 匹配且价格匹配时才会移除对象。

我可以理解给定示例中过滤器功能的工作原理,但我不确定如何干净地检查价格,最好是在 ES6 中。

【问题讨论】:

  • 我已批准更新的问题,感谢您的反馈。
  • I am currently removing duplicates objects from the array,从技术上讲你不是,你从过滤器创建一个新数组.. :)

标签: javascript arrays filter ecmascript-6


【解决方案1】:

你可以的

const rooms = [
  {
    room_rate_type_id: 202,
    price: 200
  },
  {
    room_rate_type_id: 202,
    price: 200
  },
  {
    room_rate_type_id: 202,
    price: 189
  },
  {
    room_rate_type_id: 190,
    price: 200
  }
];

let result = rooms.filter((e, i) => {
    return rooms.findIndex((x) => {
    return x.room_rate_type_id == e.room_rate_type_id && x.price == e.price;}) == i;

});

console.log(result);

这将过滤除第一次出现的任何对象之外的所有重复项

【讨论】:

  • 这是我正在寻找的干净方法。谢谢
  • 清洁解决方案!
  • 这具有二次时间复杂度。使用哈希映射方法和reducefilter 的线性时间复杂度是可能的。
【解决方案2】:

简单方法:使用room_rate_type_idprice 键的串联作为唯一键:

const rooms = [
    {room_rate_type_id: 202,price: 200},{room_rate_type_id: 202,price: 200},{room_rate_type_id: 202,price: 189},{room_rate_type_id: 190,price: 200}
];

const roomRateKeys = [];
const newRooms = rooms.filter((r, i, a) => {
    var k = r.room_rate_type_id + "" + r.price;
    if (roomRateKeys.indexOf(k) === -1) {
        roomRateKeys.push(k);
	return r;
    }
});

console.log(newRooms);

【讨论】:

    【解决方案3】:

    对于较小的数组,您可以通过重复寻找其他匹配的房间来做到这一点:

    const newRooms = rooms.filter((room, index) => {
      // Only include this room if there isn't another room earlier
      // in the array that has the same values
      return !rooms.some((r, i) =>
        i < index &&
        r.room_rate_type_id == room.room_rate_type_id &&
        r.price == room.price
      );
    });
    

    const rooms = [{
        room_rate_type_id: 202,
        price: 200
      },
      {
        room_rate_type_id: 202,
        price: 200
      },
      {
        room_rate_type_id: 202,
        price: 189
      },
      {
        room_rate_type_id: 190,
        price: 200
      }
    ];
    
    const newRooms = rooms.filter((room, index) => {
      // Only include this room if there isn't another room earlier
      // in the array that has the same values
      return !rooms.some((r, i) =>
        i < index &&
        r.room_rate_type_id == room.room_rate_type_id &&
        r.price == room.price
      );
    });
    
    console.log(newRooms);
    .as-console-wrapper {
      max-height: 100% !important;
    }

    如果数组真的很大,那效率会很低,你最好记住以前见过的组合,而不是不断地重新搜索数组:

    const seenRooms = Object.create(null);
    const newRooms = rooms.filter((room, index) => {
      const key = room.room_rate_type_id + "**" + room.price;
      if (seenRooms[key]) {
        return false;
      }
      seenRooms[key] = true;
      return true;
    });
    

    const rooms = [{
        room_rate_type_id: 202,
        price: 200
      },
      {
        room_rate_type_id: 202,
        price: 200
      },
      {
        room_rate_type_id: 202,
        price: 189
      },
      {
        room_rate_type_id: 190,
        price: 200
      }
    ];
    
    const seenRooms = Object.create(null);
    const newRooms = rooms.filter((room, index) => {
      const key = room.room_rate_type_id + "**" + room.price;
      if (seenRooms[key]) {
        return false;
      }
      seenRooms[key] = true;
      return true;
    });
    
    console.log(newRooms);
    .as-console-wrapper {
      max-height: 100% !important;
    }

    这些是为了清楚起见而写的;如果你愿意,你可以让它们更简洁。

    【讨论】:

      【解决方案4】:

      这样就可以了:

      const rooms = [{
          room_rate_type_id: 202,
          price: 200
        },
        {
          room_rate_type_id: 202,
          price: 200
        },
        {
          room_rate_type_id: 202,
          price: 189
        },
        {
          room_rate_type_id: 190,
          price: 200
        }
      ];
      
      const newRooms = rooms.reduce((rooms, room) => {
        let l = rooms.filter(r => {
          return r.room_rate_type_id === room.room_rate_type_id && r.price === room.price;
        });
        if (l.length === 0) {
          return [...rooms, room]
        }
        return rooms;
      }, [rooms[0]]);
      
      console.log(newRooms);
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      【讨论】:

        【解决方案5】:

        您可以将数组reduce 转换为Map 对象,方法是从两个属性创建一个键,并且仅当键不存在时才将该对象添加到 Map。然后将Map#values 传播回一个数组:

        const rooms = [{
            room_rate_type_id: 202,
            price: 200
          },
          {
            room_rate_type_id: 202,
            price: 200
          },
          {
            room_rate_type_id: 202,
            price: 189
          },
          {
            room_rate_type_id: 190,
            price: 200
          }
        ];
        
        const newRooms = [...rooms.reduce((m, r) => {
          const key = `${r.room_rate_type_id}-${r.price}`; // create the key by combining both props
          return m.has(key) ? m : m.set(key, r); // if key exists skip, if not add to map
        }, new Map()).values()]; // get the map values and convert back to array
        
        console.log(newRooms);

        【讨论】:

          【解决方案6】:

          const rooms = [
            {
              room_rate_type_id: 202,
              price: 200
            },
            {
              room_rate_type_id: 202,
              price: 200
            },
            {
              room_rate_type_id: 202,
              price: 189
            },
            {
              room_rate_type_id: 190,
              price: 200
            }
          ];
          
          let newRooms = rooms.filter((x, i, arr) => arr.findIndex(y => y.room_rate_type_id === x.room_rate_type_id && y.price === x.price) === i);
          
          
          console.log(newRooms);

          【讨论】:

            猜你喜欢
            • 2016-11-08
            • 2012-05-17
            • 2020-06-29
            • 2014-03-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-04-03
            • 1970-01-01
            相关资源
            最近更新 更多