如果一个元素已经存在于一个数组中,不要再添加它

我有一个像这样的对象数组:

var array = [ {id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"} ... ]; 

正如你所看到的,一些名字是重复的。 我想获得一个只有名字的新数组,但如果重复一些名字,我不想再添加它。 我想要这个数组:

 var newArray = ["Name1", "Name2"]; 

我试图用map来做到这一点:

 var newArray = array.map((a) => { return a.name; }); 

但问题是,这返回:

 newArray = ["Name1", "Name1", "Name2", "Name2"]; 

我怎样才能设置map内的一些条件,所以它不会返回一个已经存在的元素? 我想用map或其他一些ECMAScript 5或ECMAScript 6function来做到这一点。

使用ES6,可以在映射对象的名称之后使用Set作为唯一值。

这个build议使用扩展语法...来收集新数组中的项目。

 const array = [{ id: 123, value: "value1", name:"Name1" }, { id: 124, value: "value2", name: "Name1" }, { id: 125, value: "value3", name: "Name2" }, { id: 126, value: "value4", name: "Name2" }], names = [...new Set(array.map(a => a.name))]; console.log(names); 

如果您正在寻找不是ES 6(不设置)的JavaScript解决scheme,则可以使用Array的reduce方法 :

 var array=[ {id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"} ]; var names = array.reduce(function (a, b) { if (a.indexOf(b.name) == -1) { a.push(b.name) } return a; }, []); console.log(names); 

就个人而言,我不明白为什么每个人都喜欢ES 6。如果是我的代码,我宁愿支持尽可能多的浏览器。

 var array=[ {id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"} ]; // Create array of unique names var a = (function(a){ for (var i = array.length; i--;) if (a.indexOf(array[i].name) < 0) a.push(array[i].name); return a; })([]); console.log(a); 

您可以使用Array.prototype.map()函数谓词中的参数elemindexarray来获取具有对象name属性的数组,而不是Array.prototype.filter()来消除重复的元素:

 var array = [{id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"}], names = array .map(e => e.name) .filter((e, i, a) => a.indexOf(e) === i); console.log(names); 

你也可以简单地将mapfilter结合起来

 var array = [ {id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"} ]; var unique = array .map( item => item.name ) .filter( ( item, idx, arr ) => arr.indexOf( item ) == idx ) console.log(unique) 

这里有很多好的答案。 我只是想贡献一些多样性,希望给你另一种观点。

数组是JavaScript中的对象types,所以它们可以同时用作散列。 通过使用这个function,我们可以大大简化在O(n)时间复杂度的单个减less操作中要完成的工作。

如果你不喜欢你的数组持有除数组键以外的其他属性,你可能会考虑保留一个单独的哈希对象。

 var array = [{id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"} ], result = array.reduce((p,c) => p[c.name] ? p : (p[c.name] = true, p.push(c.name), p), []); console.log(result); 

我同意,如果你只需要name值, Set是要走的路。

但是 ,如果你想获得一个基于name属性的唯一对象数组,我build议使用一个Map 。 创buildMap的快捷方式是通过[key, value]数组的数组:

 const array = [{ id: 123, value: "value1", name:"Name1" }, { id: 124, value: "value2", name: "Name1" }, { id: 125, value: "value3", name: "Name2" }, { id: 126, value: "value4", name: "Name2" }], unique = new Map(array.map(obj => [obj.name, obj])); // To get the unique objects const uniques = Array.from(unique.values()); // Get the names like you already did: console.log("Names:", uniques.map(obj => obj.name)); // If you ever need the complete array of unique objects, you got a ref: console.log(JSON.stringify(uniques)); 
 .as-console-wrapper { min-height: 100%; } 

如果你仅限于ES5,我会使用Lodash的_.uniq

 var newArray = _.uniq(array.map(function(a) { return a.name; })); 

尝试这个:

 nArr = []; array.filter((a)=>{ if (nArr.indexOf(a.name) < 0) { nArr.push(a.name); return true } else { return false } }); 

有了ES6,这个工作就可以完成了。

 var array=[ {id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"} ]; var set = new Set(); array.map((a)=>{ set.add(a.name); }); console.log(Array.from(set)); 

这就是我做的,使用一个单独的空数组。

 var array = [ {id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"} ]; var array2 = [] for (i=0; i<array.length;i++){ if (array2.indexOf(array[i].name) == -1){ array2.push(array[i].name); } } console.log(array2) 

使用UnderscoreJS,

 array = [{id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"}]; get_names = _.pluck(_.uniq(array, 'name'), 'name') console.log(get_names) 
 <script src="ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 

对于那些寻求1class轮

 const names = array.reduce((acc, {name}) => acc.includes(name) ? acc : [name, ...acc], []); 

或者不使用数组原型上的方法

 const { reduce, includes } = Array; const names = reduce(array, (acc, {name}) => includes(acc, name) ? acc : [name, ...acc], []); 

可以用来编写一些纯粹的函数来处理这个问题

 const get_uniq_values = (key, arr) => reduce(arr, (a, o) => includes(a, o[key]) ? a : [o[key], ...a], []); 
 var __array=[{id:123, value:"value1", name:"Name1"},{id:124, value:"value2", name:"Name1"},{id:125, value:"value3", name:"Name2"},{id:126, value:"value4", name:"Name2"}]; function __checkArray(__obj){ var flag = true; for(let i=0; i < __array.length; i++){ if(__obj.id == __array.id){ flag = false; break; } } return flag; } var __valToPush = {id: 127, value: "value5", name: "Name3"}; if(__checkArray(__valToPush)){ __array.push(__valToPush) }