简体   繁体   English

通过 2 个匹配属性从对象数组中删除重复项

[英]Remove duplicates from array of objects by 2 matching properties

I'm trying to delete duplicate elements from a dictionary when the key values "hour_from" and "hour_to" are the same.当键值“hour_from”和“hour_to”相同时,我试图从字典中删除重复的元素。 I'm using a double for (I don't remember other less cost algorithms to do it) but I'm having problems with index values.我正在使用 double for(我不记得其他低成本算法可以做到这一点),但我在索引值方面遇到了问题。

var hours_array = [
{day: "Mon", hour_from: "00:00", hour_to: "00:00"},
{day: "Mon", hour_from: "00:00", hour_to: "00:16"},
{day: "Mon", hour_from: "00:00", hour_to: "00:16"},
{day: "Thu", hour_from: "00:00", hour_to: "00:25"},
{day: "Mon", hour_from: "00:00", hour_to: "00:33"},
{day: "Fri", hour_from: "00:00", hour_to: "00:83"},
{day: "Sat", hour_from: "02:00", hour_to: "05:33"},
{day: "Thu", hour_from: "02:00", hour_to: "05:33"},
{day: "Wed", hour_from: "12:00", hour_to: "14:00"},
{day: "Sun", hour_from: "22:25", hour_to: "13:45"}]

for (let i=0; i< hours_array.length; i++){
 for (let j=0; j<=hours_array.length; j++){
  if ((hours_array[i]['hour_from'] == hours_array[j]['hour_from']) && (hours_array[i]['hour_to'] == hours_array[j]['hour_to'])){
  delete hours_array[j];
  }
 }
}

I thought it is an error with index values:我认为这是索引值的错误:

在此处输入图片说明

Edit: Needed result:编辑:需要的结果:

var hours_array = [
{day: "Mon", hour_from: "00:00", hour_to: "00:00"},
{day: "Mon", hour_from: "00:00", hour_to: "00:16"},
{day: "Thu", hour_from: "00:00", hour_to: "00:25"},
{day: "Mon", hour_from: "00:00", hour_to: "00:33"},
{day: "Fri", hour_from: "00:00", hour_to: "00:83"},
{day: "Sat", hour_from: "02:00", hour_to: "05:33"},
{day: "Wed", hour_from: "12:00", hour_to: "14:00"},
{day: "Sun", hour_from: "22:25", hour_to: "13:45"}]

Any suggestion?有什么建议吗? Any some more efficient algorithm?有什么更有效的算法吗? Thanks for reading!谢谢阅读!

You could filter the array with the help of a Set .您可以在Set的帮助下过滤数组。

If a hash value (build from hour_from and hour_to ) is in the set, the item is filtered out.如果哈希值(从hour_fromhour_to构建)在集合中,则该项目将被过滤掉。 If not, then the hash is taken to the set and the item is used.如果不是,则将散列带到集合中并使用该项目。

 var getKey = ({ hour_from, hour_to }) => [hour_from, hour_to].join('|'), hours_array = [{ day: "Mon", hour_from: "00:00", hour_to: "00:00" }, { day: "Mon", hour_from: "00:00", hour_to: "00:16" }, { day: "Mon", hour_from: "00:00", hour_to: "00:16" }, { day: "Thu", hour_from: "00:00", hour_to: "00:25" }, { day: "Mon", hour_from: "00:00", hour_to: "00:33" }, { day: "Fri", hour_from: "00:00", hour_to: "00:83" }, { day: "Sat", hour_from: "02:00", hour_to: "05:33" }, { day: "Thu", hour_from: "02:00", hour_to: "05:33" }, { day: "Wed", hour_from: "12:00", hour_to: "14:00" }, { day: "Sun", hour_from: "22:25", hour_to: "13:45" }], unique = hours_array.filter((s => o => !s.has(getKey(o)) && s.add(getKey(o)))(new Set)); console.log(unique);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

You may go lazy way with Array.prototype.reduce() along with Array.prototype.find() .你可能会懒惰地使用Array.prototype.reduce()Array.prototype.find()

 const src = [{day:"Mon",hour_from:"00:00",hour_to:"00:00"},{day:"Mon",hour_from:"00:00",hour_to:"00:16"},{day:"Mon",hour_from:"00:00",hour_to:"00:16"},{day:"Thu",hour_from:"00:00",hour_to:"00:25"},{day:"Mon",hour_from:"00:00",hour_to:"00:33"},{day:"Fri",hour_from:"00:00",hour_to:"00:83"},{day:"Sat",hour_from:"02:00",hour_to:"05:33"},{day:"Thu",hour_from:"02:00",hour_to:"05:33"},{day:"Wed",hour_from:"12:00",hour_to:"14:00"},{day:"Sun",hour_from:"22:25",hour_to:"13:45"}], dedupe = src.reduce((res, item) => ( !res.find(({hour_from, hour_to}) => hour_from == item.hour_from && hour_to == item.hour_to) ? res.push(item) : true, res ), []) console.log(dedupe)

In this line for (let j=0; j<=hours_array.length; j++){ you can run out of the array's boundries.在这行for (let j=0; j<=hours_array.length; j++){你可以用完数组的边界。 In your situation the array.length is 10, however when you try to access the element with index 10 you get undefined, because your last index is 9. You either have to change <= to < or reduce the length by 1. See solution below:在您的情况下,array.length 为 10,但是当您尝试访问索引为 10 的元素时,您会得到未定义,因为您的最后一个索引是 9。您必须将<=更改为<或将长度减少 1。请参阅解决方案以下:

for (let i=0; i< hours_array.length; i++){
  for (let j=0; j<hours_array.length; j++){
    if ((hours_array[i]['hour_from'] == hours_array[j]['hour_from']) && (hours_array[i] 
    ['hour_to'] == hours_array[j]['hour_to'])){
      delete hours_array[j];
    }
  }
}

Edit: Ok you understand this issue, the next problem is that you delete an element if the array while you are still looping.编辑:好的,你明白这个问题,下一个问题是,如果数组仍在循环中,则删除一个元素。 There are many ways to fix this, but the easiest one is to create a new array and push the unique elements to that new array.有很多方法可以解决这个问题,但最简单的方法是创建一个新数组并将唯一元素推送到该新数组。 Let me know if you need help with that.如果您需要帮助,请告诉我。

Use reduce method with combining Object.values .使用reduce方法结合Object.values

 var hours_array = [ { day: "Mon", hour_from: "00:00", hour_to: "00:00" }, { day: "Mon", hour_from: "00:00", hour_to: "00:16" }, { day: "Mon", hour_from: "00:00", hour_to: "00:16" }, { day: "Thu", hour_from: "00:00", hour_to: "00:25" }, { day: "Mon", hour_from: "00:00", hour_to: "00:33" }, { day: "Fri", hour_from: "00:00", hour_to: "00:83" }, { day: "Sat", hour_from: "02:00", hour_to: "05:33" }, { day: "Thu", hour_from: "02:00", hour_to: "05:33" }, { day: "Wed", hour_from: "12:00", hour_to: "14:00" }, { day: "Sun", hour_from: "22:25", hour_to: "13:45" } ]; const updated = Object.values( hours_array.reduce( (acc, curr) => ({ ...acc, [`${curr.hour_from}-${curr.hour_to}`]: { ...curr } }), {} ) ); console.log(updated);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM