从JavaScript中的对象数组中删除重复项

时间:2010-02-08 00:40:34

标签: javascript arrays object duplicates

我有一个包含对象数组的对象。

things = new Object();

things.thing = new Array();

things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});

我想知道从数组中删除重复对象的最佳方法是什么。所以,例如,事情就会变成......

{place:"here",name:"stuff"},
{place:"there",name:"morestuff"}

70 个答案:

答案 0 :(得分:283)

对某些es6魔法怎么样?

things.thing = things.thing.filter((thing, index, self) =>
  index === self.findIndex((t) => (
    t.place === thing.place && t.name === thing.name
  ))
)

<强> Reference URL

更通用的解决方案是:

const uniqueArray = things.thing.filter((thing,index) => {
  return index === things.thing.findIndex(obj => {
    return JSON.stringify(obj) === JSON.stringify(thing);
  });
});

Stackblitz Example

答案 1 :(得分:125)

让我们看看...一个原始的:

var obj = {};

for ( var i=0, len=things.thing.length; i < len; i++ )
    obj[things.thing[i]['place']] = things.thing[i];

things.thing = new Array();
for ( var key in obj )
    things.thing.push(obj[key]);

好的,我认为应该这样做。看看,特拉维斯。

修改
编辑代码以正确引用place(以前的id)属性。

答案 2 :(得分:77)

如果您可以使用诸如下划线或lodash之类的Javascript库,我建议您查看其库中的_.uniq函数。来自lodash

_.uniq(array, [isSorted=false], [callback=_.identity], [thisArg])

基本上,你传入的数组在这里是一个对象文字,你传入要在原始数据数组中删除重复项的属性,如下所示:

var data = [{'name': 'Amir', 'surname': 'Rahnama'}, {'name': 'Amir', 'surname': 'Stevens'}];
var non_duplidated_data = _.uniq(data, 'name'); 

更新:Lodash现在也引入了.uniqBy

答案 3 :(得分:60)

我有完全相同的要求,根据单个字段上的重复项删除数组中的重复对象。我在这里找到了代码:Javascript: Remove Duplicates from Array of Objects

因此,在我的示例中,我从数组中删除了任何具有重复licenseNum字符串值的对象。

var arrayWithDuplicates = [
    {"type":"LICENSE", "licenseNum": "12345", state:"NV"},
    {"type":"LICENSE", "licenseNum": "A7846", state:"CA"},
    {"type":"LICENSE", "licenseNum": "12345", state:"OR"},
    {"type":"LICENSE", "licenseNum": "10849", state:"CA"},
    {"type":"LICENSE", "licenseNum": "B7037", state:"WA"},
    {"type":"LICENSE", "licenseNum": "12345", state:"NM"}
];

function removeDuplicates(originalArray, prop) {
     var newArray = [];
     var lookupObject  = {};

     for(var i in originalArray) {
        lookupObject[originalArray[i][prop]] = originalArray[i];
     }

     for(i in lookupObject) {
         newArray.push(lookupObject[i]);
     }
      return newArray;
 }

var uniqueArray = removeDuplicates(arrayWithDuplicates, "licenseNum");
console.log("uniqueArray is: " + JSON.stringify(uniqueArray));

结果:

uniqueArray是:

[{"type":"LICENSE","licenseNum":"10849","state":"CA"},
{"type":"LICENSE","licenseNum":"12345","state":"NM"},
{"type":"LICENSE","licenseNum":"A7846","state":"CA"},
{"type":"LICENSE","licenseNum":"B7037","state":"WA"}]

答案 4 :(得分:24)

使用Set

的一个班轮

&#13;
&#13;
var things = new Object();

things.thing = new Array();

things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});

// assign things.thing to myData for brevity
var myData = things.thing;

things.thing = Array.from(new Set(myData.map(JSON.stringify))).map(JSON.parse);

console.log(things.thing)
&#13;
&#13;
&#13;

说明:

  1. new Set(myData.map(JSON.stringify))使用字符串化的myData元素创建Set对象。
  2. 设置对象将确保每个元素都是唯一的。
  3. 然后我使用Array.from基于创建的集合的元素创建一个数组。
  4. 最后,我使用JSON.parse将字符串化元素转换回对象。

答案 5 :(得分:22)

如果您可以等到所有添加之后消除重复项,则典型的方法是首先对数组进行排序,然后消除重复项。当你走过它们时,排序避免了N * N方法为每个元素扫描数组。

“消除重复”功能通常称为唯一 uniq 。一些现有实现可以组合这两个步骤,例如prototype's uniq

This post几乎没有尝试的想法(有些要避免:-))如果您的图书馆还没有!就个人而言,我觉得这个最直接:

    function unique(a){
        a.sort();
        for(var i = 1; i < a.length; ){
            if(a[i-1] == a[i]){
                a.splice(i, 1);
            } else {
                i++;
            }
        }
        return a;
    }  

    // Provide your own comparison
    function unique(a, compareFunc){
        a.sort( compareFunc );
        for(var i = 1; i < a.length; ){
            if( compareFunc(a[i-1], a[i]) === 0){
                a.splice(i, 1);
            } else {
                i++;
            }
        }
        return a;
    }

答案 6 :(得分:20)

如果您只需要通过对象的一个​​字段进行比较,那么使用数组迭代方法可以做另一个选项:

    function uniq(a, param){
        return a.filter(function(item, pos, array){
            return array.map(function(mapItem){ return mapItem[param]; }).indexOf(item[param]) === pos;
        })
    }

    uniq(things.thing, 'place');

答案 7 :(得分:15)

<强>已更新

我现在已经正确地阅读了这个问题。这是执行此操作的一般方法:传入一个函数,该函数测试数组的两个元素是否相等。在这种情况下,它会比较要比较的两个对象的nameplace属性的值。

function arrayContains(arr, val, equals) {
    var i = arr.length;
    while (i--) {
        if ( equals(arr[i], val) ) {
            return true;
        }
    }
    return false;
}

function removeDuplicates(arr, equals) {
    var originalArr = arr.slice(0);
    var i, len, j, val;
    arr.length = 0;

    for (i = 0, len = originalArr.length; i < len; ++i) {
        val = originalArr[i];
        if (!arrayContains(arr, val, equals)) {
            arr.push(val);
        }
    }
}

function thingsEqual(thing1, thing2) {
    return thing1.place === thing2.place
        && thing1.name === thing2.name;
}

removeDuplicates(things.thing, thingsEqual);

答案 8 :(得分:15)

这里有一个班轮

&#13;
&#13;
let arr = [
  {id:1,name:"sravan ganji"},
  {id:2,name:"anu"},
  {id:4,name:"mammu"},
  {id:3,name:"sanju"},
  {id:3,name:"ram"},
];

console.log(Object.values(arr.reduce((acc,cur)=>Object.assign(acc,{[cur.id]:cur}),{})))
&#13;
&#13;
&#13;

答案 9 :(得分:14)

任何人都可能找不到该答案,但是这是一种比已有的50多个答案更短的ES6方法,具有更好的运行时间

let ids = array.map(o => o.id)
let filtered = array.filter(({id}, index) => !ids.includes(id, index+1))

示例:

let arr = [{id: 1, name: 'one'}, {id: 2, name: 'two'}, {id: 1, name: 'one'}]

let ids = arr.map(o => o.id)
let filtered = arr.filter(({id}, index) => !ids.includes(id, index + 1))

console.log(filtered)

工作方式:

Array.filter()通过检查先前映射的id数组是否包含当前ID来删除所有重复的对象({id}将对象分解为仅其ID)。为了仅过滤出实际的重复项,它使用Array.includes()的第二个参数fromIndexindex + 1来忽略当前对象和所有先前的对象。

由于filter回调方法的每次迭代都只会搜索从当前索引+ 1开始的数组,因此这也大大减少了运行时间,因为只有先前未过滤的对象才被检查。

显然,这也适用于任何其他不称为id的键,甚至不包括多个或所有键。

答案 10 :(得分:11)

最简单的方法是使用filter

var uniq = {}
var arr  = [{"id":"1"},{"id":"1"},{"id":"2"}]
var arrFiltered = arr.filter(obj => !uniq[obj.id] && (uniq[obj.id] = true));
console.log('arrFiltered', arrFiltered)

答案 11 :(得分:11)

我认为最好的方法是使用 reduceMap object这是单行解决方案。

const data = [
  {id: 1, name: 'David'},
  {id: 2, name: 'Mark'},
  {id: 2, name: 'Lora'},
  {id: 4, name: 'Tyler'},
  {id: 4, name: 'Donald'},
  {id: 5, name: 'Adrian'},
  {id: 6, name: 'Michael'}
]

const uniqueData = [...data.reduce((map, obj) => map.set(obj.id, obj), new Map()).values()];

console.log(uniqueData)

/*
  in `map.set(obj.id, obj)`
  
  'obj.id' is key. (don't worry. we'll get only values using the .values() method)
  'obj' is whole object.
*/

答案 12 :(得分:11)

再向列表中添加一个。将ES6和Array.reduceArray.find一起使用。
在此示例中,基于guid属性过滤对象。

let filtered = array.reduce((accumulator, current) => {
  if (! accumulator.find(({guid}) => guid === current.guid)) {
    accumulator.push(current);
  }
  return accumulator;
}, []);

扩展这个以允许选择属性并将其压缩成一个衬垫:

const uniqify = (array, key) => array.reduce((prev, curr) => prev.find(a => a[key] === curr[key]) ? prev : prev.push(curr) && prev, []);

要使用它,请传递一个对象数组以及要作为字符串值进行重复数据删除的键的名称:

const result = uniqify(myArrayOfObjects, 'guid')

答案 13 :(得分:9)

您还可以使用Map

const dedupThings = Array.from(things.thing.reduce((m, t) => m.set(t.place, t), new Map()).values());

完整样本:

const things = new Object();

things.thing = new Array();

things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});

const dedupThings = Array.from(things.thing.reduce((m, t) => m.set(t.place, t), new Map()).values());

console.log(JSON.stringify(dedupThings, null, 4));

结果:

[
    {
        "place": "here",
        "name": "stuff"
    },
    {
        "place": "there",
        "name": "morestuff"
    }
]

答案 14 :(得分:9)

Dang,孩子们,让我们粉碎这件事,为什么不呢?

let uniqIds = {}, source = [{id:'a'},{id:'b'},{id:'c'},{id:'b'},{id:'a'},{id:'d'}];
let filtered = source.filter(obj => !uniqIds[obj.id] && (uniqIds[obj.id] = true));
console.log(filtered);
// EXPECTED: [{id:'a'},{id:'b'},{id:'c'},{id:'d'}];

答案 15 :(得分:7)

另一种选择是创建一个自定义indexOf函数,该函数比较每个对象所选属性的值,并将其包含在reduce函数中。

var uniq = redundant_array.reduce(function(a,b){
      function indexOfProperty (a, b){
          for (var i=0;i<a.length;i++){
              if(a[i].property == b.property){
                   return i;
               }
          }
         return -1;
      }

      if (indexOfProperty(a,b) < 0 ) a.push(b);
        return a;
    },[]);

答案 16 :(得分:7)

考虑lodash.uniqWith

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];

_.uniqWith(objects, _.isEqual);
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]

答案 17 :(得分:5)

我知道这个问题已经有很多答案了,但是请忍受...

阵列中的某些对象可能具有您不感兴趣的其他属性,或者您只想查找仅包含属性子集的唯一对象。

考虑下面的数组。假设您要仅考虑propOnepropTwo来查找此数组中的唯一对象,而忽略那里可能存在的任何其他属性。

预期结果应仅包括第一个和最后一个对象。因此代码如下:

const array = [{
    propOne: 'a',
    propTwo: 'b',
    propThree: 'I have no part in this...'
},
{
    propOne: 'a',
    propTwo: 'b',
    someOtherProperty: 'no one cares about this...'
},
{
    propOne: 'x',
    propTwo: 'y',
    yetAnotherJunk: 'I am valueless really',
    noOneHasThis: 'I have something no one has'
}];

const uniques = [...new Set(
    array.map(x => JSON.stringify((({ propOne, propTwo }) => ({ propOne, propTwo }))(x))))
].map(JSON.parse);

console.log(uniques);

答案 18 :(得分:5)

 const things = [
  {place:"here",name:"stuff"},
  {place:"there",name:"morestuff"},
  {place:"there",name:"morestuff"}
];
const filteredArr = things.reduce((thing, current) => {
  const x = thing.find(item => item.place === current.place);
  if (!x) {
    return thing.concat([current]);
  } else {
    return thing;
  }
}, []);
console.log(filteredArr)

答案 19 :(得分:5)

这种方式对我来说很好:

// css file
@value class-to-compose from "file-where-class-is-defined.css";

.someclass {
  composes: class-to-compose;
  // other styles
}

打印输出

function arrayUnique(arr, uniqueKey) {
  const flagList = new Set()
  return arr.filter(function(item) {
    if (!flagList.has(item[uniqueKey])) {
      flagList.add(item[uniqueKey])
      return true
    }
  })
}
const data = [
  {
    name: 'Kyle',
    occupation: 'Fashion Designer'
  },
  {
    name: 'Kyle',
    occupation: 'Fashion Designer'
  },
  {
    name: 'Emily',
    occupation: 'Web Designer'
  },
  {
    name: 'Melissa',
    occupation: 'Fashion Designer'
  },
  {
    name: 'Tom',
    occupation: 'Web Developer'
  },
  {
    name: 'Tom',
    occupation: 'Web Developer'
  }
]
console.table(arrayUnique(data, 'name'))// work well

ES5:

┌─────────┬───────────┬────────────────────┐
│ (index) │   name    │     occupation     │
├─────────┼───────────┼────────────────────┤
│    0    │  'Kyle'   │ 'Fashion Designer' │
│    1    │  'Emily'  │   'Web Designer'   │
│    2    │ 'Melissa' │ 'Fashion Designer' │
│    3    │   'Tom'   │  'Web Developer'   │
└─────────┴───────────┴────────────────────┘

这两种方式更简单易懂。

答案 20 :(得分:5)

这是es6的解决方案,您只想保留最后一项。该解决方案功能齐全且符合Airbnb风格。

const things = {
  thing: [
    { place: 'here', name: 'stuff' },
    { place: 'there', name: 'morestuff1' },
    { place: 'there', name: 'morestuff2' }, 
  ],
};

const removeDuplicates = (array, key) => {
  return array.reduce((arr, item) => {
    const removed = arr.filter(i => i[key] !== item[key]);
    return [...removed, item];
  }, []);
};

console.log(removeDuplicates(things.thing, 'place'));
// > [{ place: 'here', name: 'stuff' }, { place: 'there', name: 'morestuff2' }]

答案 21 :(得分:5)

let data = [
  {
    'name': 'Amir',
    'surname': 'Rahnama'
  }, 
  {
    'name': 'Amir',
    'surname': 'Stevens'
  }
];
let non_duplicated_data = _.uniqBy(data, 'name');

答案 22 :(得分:4)

removeDuplicates()接收一个对象数组,并返回一个没有任何重复对象的新数组(基于id属性)。

const allTests = [
  {name: 'Test1', id: '1'}, 
  {name: 'Test3', id: '3'},
  {name: 'Test2', id: '2'},
  {name: 'Test2', id: '2'},
  {name: 'Test3', id: '3'}
];

function removeDuplicates(array) {
  let uniq = {};
  return array.filter(obj => !uniq[obj.id] && (uniq[obj.id] = true))
}

removeDuplicates(allTests);

预期结果:

[
  {name: 'Test1', id: '1'}, 
  {name: 'Test3', id: '3'},
  {name: 'Test2', id: '2'}
];

首先,我们将变量uniq的值设置为一个空对象。

接下来,我们筛选对象数组。筛选器会创建一个新数组,其中包含所有通过提供的功能实现的测试的元素。

return array.filter(obj => !uniq[obj.id] && (uniq[obj.id] = true));

以上,我们使用&&的短路功能。如果&&的左侧求值为true,则返回&&右侧的值。如果左侧为假,则返回&&左侧的内容。

对于每个对象(obj),我们都会在uniq中检查名为obj.id的值的属性(在这种情况下,在第一次迭代中它将检查属性'1'。)我们想要与之相反的结果(正确或错误),这就是我们使用!的原因。在!uniq [obj.id]中。如果uniq已经具有id属性,则返回true,结果为false(!),告诉过滤器函数不要添加该obj。但是,如果找不到obj.id属性,它将返回false,然后求值为true(!),并返回&&右侧的所有内容,或者返回(uniq [obj.id] = true)。这是一个真实值,它告诉filter方法将该obj添加到返回的数组中,并且还将属性{1:true}添加到uniq中。这样可以确保不会再添加任何其他具有相同ID的obj实例。

答案 23 :(得分:4)

通过Set对象的解决方案

const seen = new Set();
 const things = [
  {place:"here",name:"stuff"},
  {place:"there",name:"morestuff"},
  {place:"there",name:"morestuff"}
];

const filteredArr = things.filter(el => {
  const duplicate = seen.has(el.place);
  seen.add(el.place);
  return !duplicate;
});
console.log(filteredArr)

Set对象特征

“设置对象”中的每个值必须唯一,将检查值的相等性

Set对象的目的是根据数据类型存储唯一值,无论是原始值还是对象引用。它都有非常有用的四个实例方法addclear,{{1} }和has

唯一和数据类型功能:..

delete方法

默认情况下,它会将唯一数据推送到集合中,同时还会保留数据类型..这意味着它可以防止将重复项推送到集合中,并且默认情况下还会检查数据类型...

add方法

有时需要检查数据项是否存在于集合中。这是用于收集唯一ID或项目和数据类型的便捷方法。

has方法

它将通过识别数据类型从集合中删除特定项目。

delete方法

它将从一个特定变量中删除所有收集项,并将其设置为空对象

clear对象还具有迭代方法和更多功能。.

从这里更好地阅读: Set - JavaScript | MDN

答案 24 :(得分:3)

在一行中使用ES6,您可以通过按键获得唯一的对象列表:

const unique = [...new Map(arr.map(item => [item[key], item])).values()]

可以将其放入函数中,并在以下示例中使用:

const arr = [
  {place: "here", name: "stuff"},
  {place: "there", name: "morestuff"},
  {place: "a", name: "morestuff"},
  {place: "b", name: "morestuff"},
  {place: "c", name: "morestuff"},
  {place: "here", name: "lol"},
  {place: "there", name: "test"}
]

function getUniqueListBy(arr, key) {
    return [...new Map(arr.map(item => [item[key], item])).values()]
}

const arr1 = getUniqueListBy(arr, 'place')

console.log(arr1)


const arr2 = getUniqueListBy(arr, 'name')

console.log(arr2)

答案 25 :(得分:2)

继续探索从对象数组中删除重复项的ES6方法:将Array.prototype.filterthisArg参数设置为new Set提供了不错的选择:

const things = [
  {place:"here",name:"stuff"},
  {place:"there",name:"morestuff"},
  {place:"there",name:"morestuff"}
];

const filtered = things.filter(function({place, name}) {

  const key =`${place}${name}`;

  return !this.has(key) && this.add(key);

}, new Set);

console.log(filtered);

但是,它不能与箭头函数() =>一起使用,因为this已绑定到其词法范围。

答案 26 :(得分:2)

你听说过Lodash图书馆吗? 当您不想将逻辑应用于代码时,我建议您使用此实用程序,并使用已经优化且可靠的现有代码。

考虑制作一个像这样的数组

things.thing.push({place:"utopia",name:"unicorn"});
things.thing.push({place:"jade_palace",name:"po"});
things.thing.push({place:"jade_palace",name:"tigress"});
things.thing.push({place:"utopia",name:"flying_reindeer"});
things.thing.push({place:"panda_village",name:"po"});

请注意,如果您想保持一个属性唯一,那么您可以通过使用lodash库来做到这一点。在这里,您可以使用 _ .uniqBy

  

.uniqBy(array,[iteratee = .identity])

此方法类似于 _。uniq (它返回一个无重复版本的数组,其中只保留每个元素的第一个匹配项),除了它接受被调用的iteratee数组中的每个元素,用于生成计算唯一性的标准。​​

因此,举例来说,如果你想返回一个具有“&#39;

的唯一属性的数组

  

_。uniqBy(things.thing,&#39; place&#39;)

同样,如果您希望将唯一属性命名为&#39; name&#39;

  

_.uniqBy(things.thing,&#39; name&#39;)

希望这有帮助。

干杯!

答案 27 :(得分:2)

let myData = [{place:"here",name:"stuff"}, 
 {place:"there",name:"morestuff"},
 {place:"there",name:"morestuff"}];


let q = [...new Map(myData.map(obj => [JSON.stringify(obj), obj])).values()];

console.log(q)

使用ES6和new Map()的单线。

// assign things.thing to myData
let myData = things.thing;

[...new Map(myData.map(obj => [JSON.stringify(obj), obj])).values()];

详细信息:-

  1. 在数据列表上执行.map()并将每个对象转换为[key, value]对数组(长度= 2),第一个元素(关键字)将是stringified版本的object和second(value)本身就是object
  2. 将上面创建的数组列表添加到new Map()会将键作为stringified对象,并且任何相同的键添加都将导致覆盖现有键。
  3. 使用.values()将为MapIterator提供地图中的所有值(在我们的示例中为obj
  4. 最后,spread ...运算符使用上述步骤中的值为新数组赋值。

答案 28 :(得分:2)

 npm i lodash

 let non_duplicated_data = _.uniqBy(pendingDeposits, v => [v.stellarAccount, v.externalTransactionId].join());

答案 29 :(得分:2)

我相信reduceJSON.stringify的组合可以完美地比较对象,并有选择地添加不在累加器中的对象,这是一种优雅的方式。

请记住,JSON.stringify在极端情况下可能会成为性能问题,在极端情况下,数组具有许多对象并且它们很复杂,但在大部分时间 >,这是恕我直言的最短方法。

var collection= [{a:1},{a:2},{a:1},{a:3}]

var filtered = collection.reduce((filtered, item) => {
  if( !filtered.some(filteredItem => JSON.stringify(filteredItem) == JSON.stringify(item)) )
    filtered.push(item)
  return filtered
}, [])

console.log(filtered)

另一种写法(但效率较低):

collection.reduce((filtered, item) => 
  filtered.some(filteredItem => 
    JSON.stringify(filteredItem ) == JSON.stringify(item)) 
      ? filtered
      : [...filtered, item]
, [])

答案 30 :(得分:2)

如果您不想指定属性列表:

function removeDuplicates(myArr) {
  var props = Object.keys(myArr[0])
  return myArr.filter((item, index, self) =>
    index === self.findIndex((t) => (
      props.every(prop => {
        return t[prop] === item[prop]
      })
    ))
  )
}

OBS!与IE11不兼容。

答案 31 :(得分:2)

如果您不介意以后对您的唯一数组进行排序,这将是一个有效的解决方案:

things.thing
  .sort(((a, b) => a.place < b.place)
  .filter((current, index, array) =>
    index === 0 || current.place !== array[index - 1].place)

这样,您只需要将当前元素与数组中的前一个元素进行比较。在过滤(O(n*log(n)))之前排序一次比在每个数组元素(O(n²))中搜索整个数组中的副本要便宜。

答案 32 :(得分:1)

 var testArray= ['a','b','c','d','e','b','c','d'];

 function removeDuplicatesFromArray(arr){

 var obj={};
 var uniqueArr=[];
 for(var i=0;i<arr.length;i++){ 
    if(!obj.hasOwnProperty(arr[i])){
        obj[arr[i]] = arr[i];
        uniqueArr.push(arr[i]);
    }
 }

return uniqueArr;

}
var newArr = removeDuplicatesFromArray(testArray);
console.log(newArr);

Output:- [ 'a', 'b', 'c', 'd', 'e' ]

答案 33 :(得分:1)

对于一个可读且简单的解决方案搜索者,她是我的版本:

    function removeDupplicationsFromArrayByProp(originalArray, prop) {
        let results = {};
        for(let i=0; i<originalArray.length;i++){
            results[originalArray[i][prop]] = originalArray[i];
        }
        return Object.values(results);
    }

答案 34 :(得分:1)

从数组中删除重复对象的多种方法

let nameList = [{
  "id" : 5,
  "name" : "Johnson"
},{
  "id" : 4,
  "name" : "John"
},{
  "id" : 3,
  "name" : "Juliet"
},{
  "id" : 2,
  "name" : "Nancy"
},{
  "id" : 5,
  "name" : "Johnson"
},{
  "id" : 5,
  "name" : "Johnson"
},{
  "id": 2,
  "name": 'Nancy'
}];


let output1 = Array.from(new Set(nameList.map(list=>list.id))).map(id=>{
  return {
   id: id,
   name: nameList.find(a=>a.id===id).name
  }
})

console.log('----------------------------1st way')
console.log(output1)

let output2 = nameList.reduce((accumulator, element) => {
     if (!accumulator.find(el => el['id'] === element['id'])) {
          accumulator.push(element);
      }
     return accumulator;
   },[]);
console.log('----------------------------2nd way')
console.log(output2)


const output3 = [];
const map = new Map();
for (const object of nameList) {
    if(!map.has(object.id)){
        map.set(object.id, true);
        output3.push({
            id: object.id,
            name: object.name
        });
    }
}
console.log('----------------------------3rd way')
console.log(output3)

let output4 = [...new Set(nameList.map(s => JSON.stringify(s)))]
    .map(s => JSON.parse(s));
    
console.log('----------------------------4th way')
console.log(output4);

答案 35 :(得分:1)

  • 从 react js 中的对象数组中删除重复项(完美运行)

      let optionList = [];
          var dataArr = this.state.itemArray.map(item => {
              return [item.name, item]
          });
      var maparr = new Map(dataArr);
    
      var results = [...maparr.values()];
    
      if (results.length > 0) {
           results.map(data => {
           if (data.lead_owner !== null) {
                optionList.push({ label: data.name, value: 
                data.name });
           }
           return true;
         });
     }
     console.log(optionList)
    

答案 36 :(得分:1)

这个解决方案最适合我,通过使用 Array.from 方法,而且它更短且可读。

let person = [
{name: "john"}, 
{name: "jane"}, 
{name: "imelda"}, 
{name: "john"},
{name: "jane"}
];

const data = Array.from(new Set(person.map(JSON.stringify))).map(JSON.parse);
console.log(data);

答案 37 :(得分:1)

我的两分钱在这里。如果您知道属性的顺序相同,则可以 stringify 元素,并从数组中删除重复对象,然后再次解析该数组。像这样:

var things = new Object();

things.thing = new Array();

things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});
  
let stringified = things.thing.map(i=>JSON.stringify(i));
let unique =  stringified.filter((k, idx)=> stringified.indexOf(k) === idx)
                         .map(j=> JSON.parse(j))
console.log(unique);

答案 38 :(得分:1)

另一种方法是使用reduce函数并将一个新数组作为累加器。如果累加器数组中已经有thing具有相同的名称,则不要将其添加到那里。

let list = things.thing;
list = list.reduce((accumulator, thing) => {
    if (!accumulator.filter((duplicate) => thing.name === duplicate.name)[0]) {
        accumulator.push(thing);
    }
    return accumulator;
}, []);
thing.things = list;

我正在添加这个答案,因为我找不到与Internet Explorer 11兼容的漂亮,可读的es6解决方案(我使用babel来处理箭头功能)。问题是IE11没有Map.values()Set.values()没有填充物。出于同样的原因,我使用filter()[0]来获取第一个元素而不是find()

答案 39 :(得分:1)

您可以将Object.values()Array.prototype.reduce()结合使用:

const things = new Object();

things.thing = new Array();

things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});

const result = Object.values(things.thing.reduce((a, c) => (a[`${c.place}${c.name}`] = c, a), {})); 

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 40 :(得分:1)

Source

JSFiddle

这将删除重复的对象而无需传递任何密钥。

uniqueArray = a => [...new Set(a.map(o => JSON.stringify(o)))].map(s => JSON.parse(s));

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];

var unique = uniqueArray(objects);
console.log('Original Object',objects);
console.log('Unique',unique);

uniqueArray = a => [...new Set(a.map(o => JSON.stringify(o)))].map(s => JSON.parse(s));

    var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];

    var unique = uniqueArray(objects);
    console.log(objects);
    console.log(unique);

答案 41 :(得分:0)

该问题可以简化为从thing数组中删除重复项。

您可以通过使用对象来维护唯一的条件作为键并存储相关值,从而实现更快的O(n)解决方案(假设本机键查找可以忽略)。

基本上,该想法是通过它们的唯一键存储所有对象,以便重复项会覆盖它们自身:

const thing = [{ place: "here", name:"stuff" }, { place: "there", name:"morestuff" }, { place: "there", name:"morestuff" } ]

const uniques = {}
for (const t of thing) {
  const key = t.place + '$' + t.name  // Or whatever string criteria you want, which can be generified as Object.keys(t).join("$")
  uniques[key] = t                    // Last duplicate wins
}
const uniqueThing = Object.values(uniques)
console.log(uniqueThing)

答案 42 :(得分:0)

function dupData() {
  var arr = [{ comment: ["a", "a", "bbb", "xyz", "bbb"] }];
  let newData = [];
  comment.forEach(function (val, index) {
    if (comment.indexOf(val, index + 1) > -1) {
      if (newData.indexOf(val) === -1) { newData.push(val) }
    }
  })
}

答案 43 :(得分:0)

    function genFilterData(arr, key, key1) {
      let data = [];
      data = [...new Map(arr.map((x) => [x[key] || x[key1], x])).values()];
    
      const makeData = [];
      for (let i = 0; i < data.length; i += 1) {
        makeData.push({ [key]: data[i][key], [key1]: data[i][key1] });
      }
    
      return makeData;
    }
    const arr = [
    {make: "here1", makeText:'hj',k:9,l:99},
    {make: "here", makeText:'hj',k:9,l:9},
    {make: "here", makeText:'hj',k:9,l:9}]

      const finalData= genFilterData(data, 'Make', 'MakeText');
    
        console.log(finalData);

答案 44 :(得分:0)

如果要基于所有参数而不只是一个参数对数组进行重复数据删除。您可以使用lodash的uniqBy函数,该函数可以将函数作为第二个参数。

您将获得此一线服务:

 _.uniqBy(array, e => { return e.place && e.name })

答案 45 :(得分:0)

const objectsMap = new Map();
const placesName = [
  { place: "here", name: "stuff" },
  { place: "there", name: "morestuff" },
  { place: "there", name: "morestuff" },
];
placesName.forEach((object) => {
  objectsMap.set(object.place, object);
});
console.log(objectsMap);

答案 46 :(得分:0)

在这里,我找到了一个使用 reduce 方法从对象数组中删除重复项的简单解决方案。我正在根据对象的位置键过滤元素

const med = [
  {name: 'name1', position: 'left'},
  {name: 'name2', position: 'right'},
  {name: 'name3', position: 'left'},
  {name: 'name4', position: 'right'},
  {name: 'name5', position: 'left'},
  {name: 'name6', position: 'left1'}
]

const arr = [];
med.reduce((acc, curr) => {
  if(acc.indexOf(curr.position) === -1) {
    acc.push(curr.position);
    arr.push(curr);
  }
  return acc;
}, [])

console.log(arr)

答案 47 :(得分:0)

您可以使用 SetFilter 方法来完成此操作,

var arrObj = [{
  a: 1,
  b: 2
}, {
  a: 1,
  b: 1
}, {
  a: 1,
  b: 2
}];

var duplicateRemover = new Set();

var distinctArrObj = arrObj.filter((obj) => {
  if (duplicateRemover.has(JSON.stringify(obj))) return false;
  duplicateRemover.add(JSON.stringify(obj));
  return true;
});

console.log(distinctArrObj);

Set 是原始类型的唯一集合,因此不会直接作用于对象,但是 JSON.stringify 会将其转换为原始类型,即。 String 因此,我们可以过滤。

如果您只想根据某些特定键删除重复项,例如。 key,您可以将 JSON.stringify(obj) 替换为 obj.key

答案 48 :(得分:0)

如果你使用的是 Lodash 库,你也可以使用下面的函数。它应该删除重复的对象。

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.uniqWith(objects, _.isEqual);

答案 49 :(得分:0)

那呢:

function dedupe(arr, compFn){
    let res = [];
    if (!compFn) compFn = (a, b) => { return a === b };
    arr.map(a => {if(!res.find(b => compFn(a, b))) res.push(a)});
    return res;
}

答案 50 :(得分:0)

这是另一种查找重复数量并从数据对象中轻松删除它的技术。 &#34; dupsCount&#34;是重复文件数。先排序您的数据然后删除。它将为您提供最快的重复删除。

  dataArray.sort(function (a, b) {
            var textA = a.name.toUpperCase();
            var textB = b.name.toUpperCase();
            return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
        });
        for (var i = 0; i < dataArray.length - 1; ) {
            if (dataArray[i].name == dataArray[i + 1].name) {
                dupsCount++;
                dataArray.splice(i, 1);
            } else {
                i++;
            }
        }

答案 51 :(得分:0)

这是一个使用JavaScript的新过滤功能的解决方案,非常简单。我们假设您有一个这样的数组。

var duplicatesArray = ['AKASH','AKASH','NAVIN','HARISH','NAVIN','HARISH','AKASH','MANJULIKA','AKASH','TAPASWENI','MANJULIKA','HARISH','TAPASWENI','AKASH','MANISH','HARISH','TAPASWENI','MANJULIKA','MANISH'];

filter函数允许您使用回调函数为数组中的每个元素创建一个新数组。所以你可以像这样设置唯一的数组。

var uniqueArray = duplicatesArray.filter(function(elem, pos) {return duplicatesArray.indexOf(elem) == pos;});
  

在这种情况下,您的唯一数组将遍历重复数组中的所有值。 elem变量表示数组中元素的值(mike,james,james,alex),位置是数组中的0索引位置(0,1,2,3 ...),并且duplicatesArray.indexOf(elem)值只是原始数组中该元素第一次出现的索引。所以,因为元素&#39; james&#39;重复,当我们遍历duplicatesArray中的所有元素并将它们推送到uniqueArray时,我们第一次点击james,我们的&#34; pos&#34; value是1,我们的indexOf(elem)也是1,所以James被推到了uniqueArray。我们第二次击中詹姆斯,我们的&#34; pos&#34; value是2,并且我们的indexOf(elem)仍然是1(因为它只找到数组元素的第一个实例),因此不会推送副本。因此,我们的uniqueArray仅包含唯一值。

以上是上述功能的演示。Click Here for the above function example

答案 52 :(得分:0)

如果您需要基于对象中多个属性的唯一数组,可以使用map并组合对象的属性来执行此操作。

    var hash = array.map(function(element){
        var string = ''
        for (var key in element){
            string += element[key]
        }
        return string
    })
    array = array.filter(function(element, index){
        var string = ''
        for (var key in element){
            string += element[key]
        }
        return hash.indexOf(string) == index
    })

答案 53 :(得分:0)

任何对象数组的通用:

/**
* Remove duplicated values without losing information
*/
const removeValues = (items, key) => {
  let tmp = {};

  items.forEach(item => {
    tmp[item[key]] = (!tmp[item[key]]) ? item : Object.assign(tmp[item[key]], item);
  });
  items = [];
  Object.keys(tmp).forEach(key => items.push(tmp[key]));

  return items;
}

希望它对任何人都有帮助。

答案 54 :(得分:0)

这是如何从对象数组中删除双重性的简单方法。

我经常处理数据,这对我很有用。

const data = [{name: 'AAA'}, {name: 'AAA'}, {name: 'BBB'}, {name: 'AAA'}];
function removeDuplicity(datas){
    return datas.filter((item, index,arr)=>{
    const c = arr.map(item=> item.name);
    return  index === c.indexOf(item.name)
  })
}

console.log(removeDuplicity(data))

将打印到控制台:

[[object Object] {
name: "AAA"
}, [object Object] {
name: "BBB"
}]

答案 55 :(得分:0)

str =[
{"item_id":1},
{"item_id":2},
{"item_id":2}
]

obj =[]
for (x in str){
    if(check(str[x].item_id)){
        obj.push(str[x])
    }   
}
function check(id){
    flag=0
    for (y in obj){
        if(obj[y].item_id === id){
            flag =1
        }
    }
    if(flag ==0) return true
    else return false

}
console.log(obj)

str 是一个对象数组。存在具有相同值的对象(这里是一个小例子,有两个对象具有与2相同的item_id)。 check(id)是一个检查是否存在任何具有相同item_id的对象的函数。如果存在则返回false否则返回true。根据该结果,将对象推入新阵列 obj 上面代码的输出是 [{"item_id":1},{"item_id":2}]

答案 56 :(得分:0)

function filterDuplicateQueries(queries){
    let uniqueQueries = [];
     queries.forEach((l, i)=>{
        let alreadyExist = false;
        if(uniqueQueries.length>0){
            uniqueQueries.forEach((k, j)=>{
                if(k.query == l.query){
                    alreadyExist = true;
                }
            });
        }
        if(!alreadyExist){
           uniqueQueries.push(l)
        }
    });

答案 57 :(得分:0)

  • 该解决方案对于任何类型的对象都是通用的,并检查数组(key, value)中每个Object
  • 使用一个临时对象作为哈希表,以查看整个Object是否曾经作为键出现。
  • 如果找到了Object的字符串表示形式,则将该项目从数组中删除。

var arrOfDup = [{'id':123, 'name':'name', 'desc':'some desc'},
                {'id':125, 'name':'another name', 'desc':'another desc'},
                {'id':123, 'name':'name', 'desc':'some desc'},
                {'id':125, 'name':'another name', 'desc':'another desc'},
                {'id':125, 'name':'another name', 'desc':'another desc'}];

function removeDupes(dupeArray){
  let temp = {};
  let tempArray = JSON.parse(JSON.stringify(dupeArray));
  dupeArray.forEach((item, pos) => {
    if(temp[JSON.stringify(item)]){
      tempArray.pop();
    }else{
      temp[JSON.stringify(item)] = item;
    }
  });
 return tempArray;
}

arrOfDup = removeDupes(arrOfDup);

arrOfDup.forEach((item, pos) => {
  console.log(`item in array at position ${pos} is ${JSON.stringify(item)}`);
});

答案 58 :(得分:0)

ES6魔术在一行中...可读性强!

@Entity
public class Item {
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "production_input", inverseJoinColumns        
    @JoinColumn(name = "production_id"))
    private List<Production>                inputProduction; 
}

@Service
public class ItemService {
    @Autowired
    @Qualifier("entityManagerFactory")
    private EntityManagerFactory emFactory;
    @Autowired
    private ItemRepository itemRepository;
    @Autowired
    private ProductionService productionService;

    public update(Item item) {
       EntityManager entityManager = emFactory.createEntityManager();
       Item oldItem = entityManager.find(item.getClass(),item.getId());
       this.itemRepository().save(item);
       this.productionService.asyncComputeProductionUpdate(oldItem, item,this);
    }

    public void computeProductionUpdate(Item oldItem,Item item){
     .... //use of oldItem and new item.
    }
 }

@Service
public class ProductionService {
    @Autowired
    private AsyncProductionProcess asyncProductionProcess;

    @Async
    public void asyncComputeProductionUpdate(Item oldItem,Item item,ItemService itemService) {

    this.asyncProductionProcess.setProductionService(itemService);
    this.asyncProductionProcess.asyncComputeProductionUpdate(oldItem, item);
    }
}

@Service
public class AsyncProductionProcess {
    private ItemService itemService;

    public void setItemService(ItemService itemService ) {
        this.itemService = itemService ;
    }

    @Transactional
    public void asyncComputeProductionUpdate(Item oldItem, Item item) {
        this.itemService.computeProductionUpdate(oldItem, item);
   }
}

答案 59 :(得分:0)

这是我的解决方案,它基于object.prop搜索重复项,并在找到重复对象时在array1 replaces its valuewith array2 value

function mergeSecondArrayIntoFirstArrayByProperty(array1, array2) {
    for (var i = 0; i < array2.length; i++) {
        var found = false;
        for (var j = 0; j < array1.length; j++) {
            if (array2[i].prop === array1[j].prop) { // if item exist in array1
                array1[j] = array2[i]; // replace it in array1 with array2 value
                found = true;
            }
        }
        if (!found) // if item in array2 not found in array1, add it to array1
            array1.push(array2[i]);

    }
    return array1;
}

答案 60 :(得分:0)

您还可以创建一个通用函数,该函数将根据传递给该函数的对象键来过滤数组

function getUnique(arr, comp) {

  return arr
   .map(e => e[comp])
   .map((e, i, final) => final.indexOf(e) === i && i)  // store the keys of the unique objects
   .filter(e => arr[e]).map(e => arr[e]); // eliminate the dead keys & store unique objects

 }

您可以像这样调用该函数

getUnique(things.thing,'name') // to filter on basis of name

getUnique(things.thing,'place') // to filter on basis of place

答案 61 :(得分:0)

如果发现自己需要经常根据特定的字段从数组中删除重复的对象,则可能值得创建一个distinct(array, predicate)函数,该函数可以从项目中的任何位置导入。看起来像

const things = [{place:"here",name:"stuff"}, ...];
const distinctThings = distinct(things, thing => thing.place);

distinct函数可以使用上面许多好的答案中给出的任何实现。最简单的使用findIndex

const distinct = (items, predicate) => items.filter((uniqueItem, index) =>
    items.findIndex(item =>
        predicate(item) === predicate(uniqueItem)) === index);

答案 62 :(得分:0)

const uniqueElements = (arr, fn) => arr.reduce((acc, v) => {
    if (!acc.some(x => fn(v, x))) { acc.push(v); }
    return acc;
}, []);

const stuff = [
    {place:"here",name:"stuff"},
    {place:"there",name:"morestuff"},
    {place:"there",name:"morestuff"},
];

const unique = uniqueElements(stuff, (a,b) => a.place === b.place && a.name === b.name );
//console.log( unique );

[{
    "place": "here",
    "name": "stuff"
  },
  {
    "place": "there",
    "name": "morestuff"
}]

答案 63 :(得分:0)

使事情变得简单。花哨的东西很好,但是不可读的代码是没有用的。享受:-)

var a = [
	{
		executiveId: 6873702,
		largePhotoCircle: null,
		name: "John A. Cuomo",
		photoURL: null,
		primaryCompany: "VSE CORP",
		primaryTitle: "Chief Executive Officer, President and Director"
	},
	{
		executiveId: 6873702,
		largePhotoCircle: null,
		name: "John A. Cuomo",
		photoURL: null,
		primaryCompany: "VSE CORP",
		primaryTitle: "Chief Executive Officer, President and Director"
	},
	{
		executiveId: 6873703,
		largePhotoCircle: null,
		name: "John A. Cuomo",
		photoURL: null,
		primaryCompany: "VSE CORP",
		primaryTitle: "Chief Executive Officer, President and Director",
	}
];

function filterDuplicate(myArr, prop) {
      // Format - (1)

      // return myArr.filter((obj, pos, arr) => {
      //     return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos;
      // });

      // Format - (2)
      var res = {};
      var resArr = [];
      for (var elem of myArr) {
        res[elem.executiveId] = elem;
      }
      for (let [index, elem] of Object.entries(res)) {
        resArr.push(elem);
      }
      return resArr;
  }
  
let finalRes = filterDuplicate(a,"executiveId");
console.log("finalResults : ",finalRes);

答案 64 :(得分:0)

您可以将数组对象转换为字符串,以便进行比较,将字符串添加到Set中,这样可比较的重复项将被自动删除,然后将每个字符串转换回对象。

它的性能可能不如其他答案,但是可读。

const things = {};

things.thing = [];
things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});

const uniqueArray = (arr) => {

  const stringifiedArray = arr.map((item) => JSON.stringify(item));
  const set = new Set(stringifiedArray);

  return Array.from(set).map((item) => JSON.parse(item));
}

const uniqueThings = uniqueArray(things.thing);

console.log(uniqueThings);

答案 65 :(得分:0)

TypeScript解决方案

这将删除重复的对象,并保留对象的类型。

function removeDuplicateObjects(array: any[]) {
  return [...new Set(array.map(s => JSON.stringify(s)))]
    .map(s => JSON.parse(s));
}

答案 66 :(得分:0)

具有ES6“减少”和“查找”阵列辅助方法的简单解决方案

有效且完美地工作!

"use strict";

var things = new Object();
things.thing = new Array();
things.thing.push({
    place: "here",
    name: "stuff"
});
things.thing.push({
    place: "there",
    name: "morestuff"
});
things.thing.push({
    place: "there",
    name: "morestuff"
});

// the logic is here

function removeDup(something) {
    return something.thing.reduce(function (prev, ele) {
        var found = prev.find(function (fele) {
            return ele.place === fele.place && ele.name === fele.name;
        });
        if (!found) {
            prev.push(ele);
        }
        return prev;
    }, []);
}
console.log(removeDup(things));

答案 67 :(得分:0)

最短的一个班轮

在数组中查找唯一ID。

[
    "Jenkins_Spot_Slave",
    "Jenkins_Persistant_RPM_AMI",
    "Jenkins_slave",
    "Jenkins_Image",
    "Jenkins_2.173-f42de1ed-a17a-4d6f-ab78-60f840d38dbb-ami-0f4ed2a00254db81a.4"
]

由多个属性(id和name)唯一

$List2 = foreach ($m in $MainList.'System Name') {
    Get-MdbcData (New-MdbcQuery Asset -eq $m)
}
$Business = $List2.Location
$overlist = $MainList |
            Select-Object 'System Name', @{Name='Name';Expression={$Business}}

答案 68 :(得分:0)

如果严格要基于一个属性删除重复项,则可以根据reduce属性place将数组values放入对象,因为对象只能具有唯一键,则可以获取const unique = Object.values(things.thing.reduce((o, t) => ({ ...o, [t.place]: t }), {})) 返回数组:

[{ name: 'Dave', groupid: '1' },
  { name: 'Bob', groupid: '1' },
  { name: 'Jessica', groupid: '2' },
  { name: 'Natalie', groupid: '3' }]

答案 69 :(得分:-1)

var things = new Object();

things.thing = new Array();

things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});
console.log(things);
function removeDuplicate(result, id) {
    let duplicate = {};
    return result.filter(ele => !duplicate[ele[id]] &&                   (duplicate[ele[id]] = true));
}
let resolverarray = removeDuplicate(things.thing,'place')
console.log(resolverarray);