从字典数组中获取唯一的字典?

时间:2019-03-09 01:31:42

标签: javascript reactjs

我有一个看起来像这样的数组:

dateArray = [
      {year:'2018', month: "01"},
      {year:'2018', month: "01"},
      {year:'2017', month: "02"},
      {year:'2017', month: "02"}
    ];

我想从该数组中获取唯一值,并尝试这样做:

  let unique = [...new Set(this.state.dateArray.map(item => item.Group))];
  console.log('UNIQUE: ',unique);

此解决方案不起作用。如何将唯一字典放入一个字典数组中,并将其放入一个新数组中?

4 个答案:

答案 0 :(得分:2)

可能有一种更清洁的方法,但这会删除数组的重复数据:

const dateArray = [
  {year:'2018', month: "01"},
  {year:'2018', month: "01"},
  {year:'2017', month: "02"},
  {year:'2017', month: "02"}
];

const uniqueDates = [];
for (let date of dateArray){ // Use "of" to loop through an array
  let unique = true; // Set a flag to handle possible unwanted items 
  for (let uniqueDate of uniqueDates){
    if (uniqueDate.year == date.year && uniqueDate.month == date.month){
      unique = false; // Both properties match, so throw up the flag
    }
  }
  if(unique){ // Only add the item if the flag didn't go up
    uniqueDates.push(date);
  }
}
console.log(uniqueDates);

还是同一件事,但是使用.forEach(将回调函数作为参数,可以是ES6 arrow function。)

const uniqueDates = [];
dateArray.forEach(date => { // the argument passed to the callback stores the current item
  let unique = true;
  uniqueDates.forEach(uniqueDate => {
    if (uniqueDate.year == date.year && uniqueDate.month == date.month){
      unique = false;    
    }
  });
  if(unique){
    uniqueDates.push(date);
  }
});
console.log(uniqueDates);

答案 1 :(得分:2)

因此,您想要一个删除重复项的新数组吗?您可以将数组.filter()缩小到对象,在其中使用.findIndex会产生与当前索引相同的索引:

dateArray = [
  {year:'2018', month: "01"},
  {year:'2018', month: "01"},
  {year:'2017', month: "02"},
  {year:'2017', month: "02"}
];
    
var unique = dateArray.filter((o, i) =>
  i === dateArray.findIndex(oo => o.year === oo.year && o.month === oo.month)
);

console.log(unique);
<pre></pre>

答案 2 :(得分:1)

Set是处理唯一性的适当数据类型。不幸的是,在JS中,这些仅处理原始和引用相等。但是,通过在原始字符串之间进行数据转换,我们可以使用它直接处理唯一性问题。

这是一个这样做的版本:

const uniqDates = ds => [...new Set(ds.map(({year, month}) => `${year}-${month}`))]
  .map(s => s.split('-'))
  .map(([year, month]) => ({year, month}))

const dateArray = [
  {year:'2018', month: "01"},
  {year:'2018', month: "01"},
  {year:'2017', month: "02"},
  {year:'2017', month: "02"}
]

console.log(uniqDates(dateArray))

答案 3 :(得分:1)

在O(n)时间内快速除污:

const dateArray = [
  {year:'2018', month: "01"},
  {year:'2018', month: "01"},
  {year:'2017', month: "02"},
  {year:'2017', month: "02"},
];
console.log(Array.from(new Set(dateArray.map(d => JSON.stringify([d.year, d.month])))).map(
    s => {
        const d = JSON.parse(s);
        return {year: d[0], month: d[1]};
    }
))

除了串化对象外,我不知道一种将对象轻松视为可比较值的一般方法。同样,JSON.stringify(d)也不合适,因为对象字段的序列化顺序不确定,因此需要对字段进行显式打包和拆包。真可惜,因为它本来可以简单得多:

# WRONG, DO NOT USE!
Array.from(new Set(dateArray.map(JSON.stringify))).map(JSON.parse)