如何根据2个属性删除数组中的重复对象?

时间:2017-09-25 09:53:24

标签: javascript arrays filter ecmascript-6

我有一组房间对象,我目前正在根据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中。

6 个答案:

答案 0 :(得分:2)

你可以做到

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);

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

答案 1 :(得分:1)

简单方法:使用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);

答案 2 :(得分:1)

对于小型阵列,您可以通过重复寻找其他匹配的房间来实现:

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;
}

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

答案 3 :(得分:1)

您可以通过从两个属性创建密钥,将reduce数组Map转换为Map#values对象,并且仅当密钥尚不存在时才将对象添加到Map。然后将https://eval.in/867628传播回数组:

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);

答案 4 :(得分:0)

这样就可以了:

&#13;
&#13;
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);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 5 :(得分:0)

&#13;
&#13;
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);
&#13;
&#13;
&#13;