使用Angular 4在对象数组中删除重复项

6

我有一个包含以下项目列表的数组,如图所示,我想从该数组中删除重复项 [L7-LO, %L7-LO]

Array with repetitions
我已尝试以下条件:

情况1:

this.formulalist.filter((el, i, a) => i == a.indexOf(el))

Scenario 2:
情景二:
Observable.merge(this.formulalist).distinct((x) => x.Value)
          .subscribe(y => {
       this.formulalist.push(y)
   });

Scenario 3:

this.formulalist.forEach((item, index) => {
        if (index !== this.formulalist.findIndex(i => i.Value == item.Value)) 
        {
            this.formulalist.splice(index, 1);
        }

    });

以上三种情况都无法从该数组中删除重复项。请问有人能帮忙解决这个问题吗?


你能把你的数组也发一下吗? - Piyush Khanna
你能为我们提供数组和期望的结果吗?谢谢。 - Mathias Gheno Azzolini
你的第三种情况有一定的正确性,但它不起作用是因为findIndex会给出第一个索引,尝试循环现有数组,但填充一个新数组,在新数组中执行findIndex。此外,你不应该在正在循环的同一数组上进行splice操作,否则它将开始跳过元素。 - Ashish Ranjan
7个回答

6

Angular并不一定需要使用VanillaJS。 筛选只出现一次的元素,并将第一次出现的元素添加到新列表中。

let newFormulalist =  formulalist.filter((v,i) => formulalist.findIndex(item => item.value == v.value) === i);

5
尝试创建一个没有重复项的新数组。稍后将新数组分配给formulalist。
newArr = []
this.formulalist.forEach((item, index) => {
    if (this.newArr.findIndex(i => i.Value == item.Value) === -1) 
    {
        this.newArr.push(item)
    }

});
this.formulalist = this.newArr

编辑

看上面的答案,解决方案似乎已经过时了。更好的方法是使用Array.filter()而不是Array.forEach()

但是,有一个更好的解决方案会更好,现在当我看到这个问题时,我觉得findIndex()不是一个好的方法,因为它需要额外的遍历。

我可以使用一个Set并将我想要过滤的值存储在Set中,如果Set有这些条目,我将跳过数组中的这些元素。

或者一个更好的方法是Akitha_MJ所使用的方法,非常简洁。在数组长度的一个循环中,使用一个Object(Map),其中键是我们想要删除重复项的值,值是完整的Object(Array element)本身。在循环中重复元素时,该元素将被简单地替换在Map中。稍后只需从Map中取出值即可。


3
const result = Array.from(this.item.reduce((m, t) => m.set(t.name, t), new Map()).values());

希望这能够起作用!!

2
// user reduce method to remove duplicates from object array , very easily

  this.formulalist= this.formulalist.reduce((a, b) => {
      if (!a.find(data => data.name === b.name)) {
        a.push(b);
      }
      return a;
    }, []);

// o/p = in formulalist you will find only unique values

欢迎来到 Stack Overflow。 虽然这段代码可能解决了问题,但包括解释它是如何解决问题的以及为什么能够解决问题,将有助于提高您的帖子质量,并可能导致更多的赞。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释,并指出适用的限制和假设。 - Pawara Siriwardhane

0
使用一个 reducer 返回一个新的唯一对象数组:

const input = [{
    value: 'L7-LO',
    name: 'L7-LO'
  },
  {
    value: '%L7-LO',
    name: '%L7-LO'
  },
  {
    value: 'L7-LO',
    name: 'L7-LO'
  },
  {
    value: '%L7-LO',
    name: '%L7-LO'
  },
  {
    value: 'L7-L3',
    name: 'L7-L3'
  },
  {
    value: '%L7-L3',
    name: '%L7-L3'
  },
  {
    value: 'LO-L3',
    name: 'LO-L3'
  },
  {
    value: '%LO-L3',
    name: '%LO-L3'
  }
];
console.log(input.reduce((acc, val) => {
  if (!acc.find(el => el.value === val.value)) {
    acc.push(val);
  }
  return acc;
}, []));


0
过滤唯一值时,通过将值分配给某些对象属性,速度更快 - 不会有重复项。 这种方法随着初始数组的每个+1成员而变得越来越好,因为循环将导致快速算法复杂性。

let arr = [
  {value: 'L7-LO', name: 'L7-LO'},
  {value: '%L7-LO', name: '%L7-LO'},
  {value: 'L7-LO', name: 'L7-LO'},
  {value: '%L7-LO', name: '%L7-LO'},
  {value: 'L7-L3', name: 'L7-L3'},
  {value: '%L7-L3', name: '%L7-L3'},
  {value: 'LO-L3', name: 'LO-L3'},
  {value: '%LO-L3', name: '%LO-L3'}
];
let obj = {};

const unique = () => {
  let result = [];
  
  arr.forEach((item, i) => {
    obj[item['value']] = i;
  });
  
  for (let key in obj) {
    let index = obj[key];
    result.push(arr[index])
  }
  
  return result;
}

arr = unique(); // for example; 

console.log(arr);


请问您能否更新一下如何将结果重新分配回公式列表。 - Glory Raj
unique() - 是一个函数,它返回一个新的数组,其中包含从初始数组中“过滤”后的值。但是您有相当大的灵活性。 - Dasha Ermolova
主要思路是:1)只循环一次,并将数组项和索引存储在某个辅助对象的键值对中;2)之后您肯定没有重复项,因为对象不能具有两个完全相同的属性名称,它会覆盖重复的属性。 - Dasha Ermolova

0

如果你使用 ES6 或更高版本进行编程,使用 map 和 filter 函数可以轻松实现基本的 JS 编程。

var array = [{value:"a"},{value:"b"},{value:"c"},{value:"a"},{value:"c"},{value:"d"}];

console.log(array.filter((obj, pos, arr) => {
    return arr.map(mapObj => mapObj["value"]).indexOf(obj["value"]) === pos;
}));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接