【问题标题】:Filtering an array of objects that contain arrays过滤包含数组的对象数组
【发布时间】:2019-07-30 02:53:55
【问题描述】:

这是我拥有的数组的较小版本,但结构相同

使用下面的 const arr,我想创建 2 个具有唯一值的新数组,这些数组按升序排序

const arr = [{
    tags: ['f', 'b', 'd'],
    weight: 7,
    something: 'sdfsdf'
  },
  {
    tags: ['a', 'b', 'c', 'd', 'e'],
    weight: 6,
    something: 'frddd'
  },
  {
    tags: ['f', 'c', 'e', 'a'],
    weight: 7,
    something: 'ththh'
  },
  {
    tags: ['a', 'c', 'g', 'e'],
    weight: 5,
    something: 'ghjghj'
  }
];

const finalTags = [];
const finalWeight = [];

// TODO:  find a better way to do this
arr.forEach(v => {
  if (finalWeight.indexOf(v.weight) === -1) finalWeight.push(v.weight);
  v.tags.forEach(val => {
    if (finalTags.indexOf(val) === -1) finalTags.push(val);
  });
});

// Ascending order
finalTags.sort();
finalWeight.sort();

我上面的作品,但似乎有点凌乱,如果有更好/更整洁的方式来做这件事,我会徘徊

【问题讨论】:

标签: javascript arrays sorting ecmascript-6


【解决方案1】:

您可以将Array.prototype.reduce()Set 结合使用,以获取具有排序数组{tags: [], weights: []} 的对象:

const arr = [{tags: ['f', 'b', 'd'],weight: 7,something: 'sdfsdf'},{tags: ['a', 'b', 'c', 'd', 'e'],weight: 6,something: 'frddd'},{tags: ['f', 'c', 'e', 'a'],weight: 7,something: 'ththh'},{tags: ['a', 'c', 'g', 'e'],weight: 5,something: 'ghjghj'}];
const obj = arr.reduce((a, {tags, weight}) => {
  a.tags = [...new Set(a.tags.concat(tags))];
  a.weights = [...new Set(a.weights.concat(weight))];
  return a;
}, {tags: [], weights: []});

// final result i want
console.log('finalTags:', obj.tags.sort()); // ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
console.log('finalWeight:', obj.weights.sort()); // [5, 6, 7];
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 我会投票给你,因为你和我有相似的想法并且是第一个。不过,也很高兴看到一些解释。
  • 感谢您的评论@Shidersz。我添加了一个更好的描述,你也有我的..
  • 比我的版本好多了,谢谢大家的回答
【解决方案2】:

一种解决方案是使用Array.reduce() 创建两组,一组使用tags,另一组使用weights。在此之后,您可以将sets 转换为arrays 并在它们上使用Array.sort()

const arr = [
  {
    tags: ['f', 'b', 'd'],
    weight: 7,
    something: 'sdfsdf'
  },
  {
    tags: ['a', 'b', 'c', 'd', 'e'],
    weight: 6,
    something: 'frddd'
  },
  {
    tags: ['f', 'c', 'e', 'a'],
    weight: 7,
    something: 'ththh'
  },
  {
    tags: ['a', 'c', 'g', 'e'],
    weight: 5,
    something: 'ghjghj'
  }
];

let res = arr.reduce((acc, {tags, weight}) =>
{
    acc.tags = new Set([...acc.tags, ...tags]);
    acc.weights.add(weight);
    return acc;
}, {tags: new Set(), weights: new Set()});

let sortedWeigths = [...res.weights].sort();
let sortedTags = [...res.tags].sort((a, b) => a.localeCompare(b));
console.log("weights: ", sortedWeigths, "tags: ", sortedTags);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

【讨论】:

    【解决方案3】:

    您可以使用以下代码。这基本上将arr 拆分为finalTagsfinalWeights

    .flat() 将数组展平([1, [2, [3]]] 将变为 [1, 2, 3]

    finalTags.filter((item, index) => finalTags.indexOf(item) >= index).sort(); 删除重复项。

    const arr = [{
        tags: ['f', 'b', 'd'],
        weight: 7,
        something: 'sdfsdf'
      },
      {
        tags: ['a', 'b', 'c', 'd', 'e'],
        weight: 6,
        something: 'frddd'
      },
      {
        tags: ['f', 'c', 'e', 'a'],
        weight: 7,
        something: 'ththh'
      },
      {
        tags: ['a', 'c', 'g', 'e'],
        weight: 5,
        something: 'ghjghj'
      }
    ];
    
    let finalTags = arr.map(e => e.tags);
    finalTags = finalTags.flat();
    finalTags = finalTags.filter((item, index) => finalTags.indexOf(item) >= index).sort();
    
    let finalWeight = arr.map(e => e.weight);
    finalWeight = finalWeight.filter((item, index) => finalWeight.indexOf(item) >= index).sort();
    
    console.log(finalTags);
    console.log(finalWeight);

    来源:

    删除重复项:https://gomakethings.com/removing-duplicates-from-an-array-with-vanilla-javascript/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-15
      • 2017-01-28
      • 2021-08-28
      • 1970-01-01
      • 1970-01-01
      • 2019-11-25
      • 2019-10-01
      • 1970-01-01
      相关资源
      最近更新 更多