代码之家  ›  专栏  ›  技术社区  ›  arcade16

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

  •  0
  • arcade16  · 技术社区  · 5 年前

    我有一个这样的数组:

    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 回复  |  直到 5 年前
        1
  •  2
  •   Cat    5 年前

    可能有一种更干净的方法,但这种方法会消除阵列中的重复数据:

    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 arrays
      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);
    
        2
  •  1
  •   ziggy wiggy    5 年前

    所以要删除重复项的新数组吗?你可以 .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>
        3
  •  1
  •   Scott Sauyet    5 年前

    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))
        4
  •  0
  •   Marcelo Cantos    5 年前

    快干时间:

    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)