获取重复项,但对象数组中首次出现的除外

时间:2019-02-14 07:55:06

标签: javascript

我希望能够根据位置和关键字返回除第一次出现在对象数组中以外的重复项。两者都应匹配并以新数组返回文档。这是我的试运行:

var things = [
                {place: 'hello', keyword: 'hey', id: 0},
                {place: 'hi', id: 1},
                {place: 'hello', keyword: 'hey', id: 2},
                {place: 'hello', keyword: 'man', id: 3}
            ]
var duplicates = [];

things.forEach((item, index) => {
    if(things.indexOf(item.place) != index && things.indexOf(item.keyword) != index) {
        duplicates.push(item);
    }
});

预期输出:

[{place: 'hello', keyword: 'hey', id: 2}]

任何帮助都会很棒(没有任何框架,只有ES6或更旧的框架)。谢谢

编辑:它应该匹配多个指定的值,例如关键字和位置。

3 个答案:

答案 0 :(得分:2)

如果要计数的对象大于一个,则可以对相同的键进行计数并进行过滤

const
    getKey = o => keys.map(k => o[k]).join('|'),
    keys = ['place', 'keyword'],
    things = [{ place: 'hello', keyword: 'hey', id: 0 }, { place: 'hi', id: 1 }, { place: 'hello', keyword: 'hey', id: 2 }, { place: 'hello', keyword: 'man', id: 3 }],
    hash = Object.create(null),
    duplicates = things.filter(o =>
        (k => (hash[k] = (hash[k] || 0) + 1) > 1)
        (getKey(o))
    );
  
console.log(duplicates);

答案 1 :(得分:0)

您可以根据place对项目进行分组,然后使用length > 1从这些组中获取第一项

const things = [{ place: 'hello', keyword: 'hey', id: 0 }, { place: 'hi', id: 1 }, { place: 'hello', keyword: 'hey', id: 2 }, { place: 'hello', keyword: 'man', id: 3 }];

const merged = things.reduce((r, a) => {
  (r[a.place] = r[a.place] || []).push(a)
  return r
}, {})

const final = Object.values(merged)
                    .filter(a => a.length > 1)
                    .map(a => a[1])

console.log(final)

答案 2 :(得分:0)

一种明显的解决方案是,您必须跟踪看到的对象才能按照自己的意愿进行操作。

const seen = [];
const duplicates = [];

things.forEach(item => {
  const sawItem = seen.find(seenItem => item.place === seenItem.place && item.keyword === seenItem.keyword)
  if (sawItem) {
     duplicates.push(sawItem);
  } else {
    seen.push(sawItem);
  }
});

但是,这并不是一种非常有效的算法,所以我很好奇看到了一种更好的方法。