如果元素中已存在元素,请不要再次添加

sno*_*y25 97 javascript arrays

我有一个对象数组,如下所示:

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"}
    ...
];
Run Code Online (Sandbox Code Playgroud)

如您所见,有些名称会重复出现.我想获得一个只有名字的新数组,但是如果某些名称重复,我不想再添加它.我想要这个数组:

var newArray = ["Name1", "Name2"];
Run Code Online (Sandbox Code Playgroud)

我正在尝试这样做map:

var newArray = array.map((a) => {
    return a.name;
});
Run Code Online (Sandbox Code Playgroud)

但问题是这会返回:

newArray = ["Name1", "Name1", "Name2", "Name2"];
Run Code Online (Sandbox Code Playgroud)

我怎样才能在里面设置一些条件map,所以它不会返回已经存在的元素?我想用map或其他一些ECMAScript 5或ECMAScript 6功能.

Nin*_*olz 199

使用ES6,Set只能映射对象的名称后,可以使用唯一值.

此提议使用扩展语法...来收集新数组中的项目.

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);
Run Code Online (Sandbox Code Playgroud)

  • 这只是我个人的意见,但是[相当常见](http://stackoverflow.com/a/40549565/1048572).使用`Array.from`可以更好地传达转换的意图(也更容易理解/搜索新手),只有在spreaded元素是众多元素之一时才应使用扩展语法.也许称之为"不良做法"有点过于苛刻,抱歉,我只是希望能够阻止它成为一种常见的习语. (32认同)
  • @RajshekarReddy,它是[spread语法`...`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator),用于构建带有可迭代对象的数组. (9认同)
  • 对于我的信息......```做什么? (8认同)
  • 我并不赞成"Set"本身,而是为了巧妙地使用spread运算符.学习新东西或看到一些新的东西适用于实际例子总是很好的,所以这篇文章值得投票. (5认同)
  • @KRyan是ES6这么新吗?它已于2015年6月完成.是时候开始理解和使用新功能了 (3认同)

Dek*_*kel 62

如果您正在寻找不是ES 6(无Set)的JavaScript解决方案,您可以使用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);
Run Code Online (Sandbox Code Playgroud)

  • @Rayon请不要过多关注源代码的大小,这是许多自制程序员常见的陷阱,最重要的是,你的程序应该高效可读. (3认同)
  • 这个答案的好处是它不需要中间数组或集合,特别是那些只包含名称本身的数组或集合.(它直接从对象数组到对象数组.)+ 1 (2认同)

I w*_*ce. 16

就个人而言,我不明白为什么每个人都对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);
Run Code Online (Sandbox Code Playgroud)

  • "我个人不明白为什么每个人都对es6有所了解"为什么你要求'goto fail`,将你的索引变量泄漏到封闭的范围等等.ES6被编入标准有充分理由,在大多数情况下,对于旧浏览器来说,很容易填充/转换. (7认同)
  • 更具可读性?它是一个将项目推送到阵列上的怪物.没有比那更具可读性...... (5认同)
  • 老实说,只是觉得你很难找到抱怨的东西. (4认同)
  • 使用对象作为字典而不是一直使用`indexOf`会不会更高效?例如`添加[name] = true`和`if(added [name])`而不是`if(a.indexOf(name))`. (2认同)
  • "我指的是着名的Apple SSL漏洞" - 并不是那么着名,你可以随意在随机评论中引用它并期望人们认识到它. (2认同)

Dav*_*ain 14

你也可以简单地结合起来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)
Run Code Online (Sandbox Code Playgroud)


Yos*_*ero 11

您可以使用参数获取Array.prototype.map()以获取具有objects name属性和Array.prototype.filter()的数组elem,indexarray在函数谓词中消除重复的元素:

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);
Run Code Online (Sandbox Code Playgroud)


Red*_*edu 7

这里有很多好的答案.我只想提供一些多样性,希望能给你另一个视角.

数组在JavaScript中是对象类型,因此它们可以同时用作哈希.通过使用此功能,我们可以极大地简化在O(n)时间复杂度的单个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"}
            ],
result = array.reduce((p,c) => p[c.name] ? p : (p[c.name] = true, p.push(c.name), p), []);
console.log(result);
Run Code Online (Sandbox Code Playgroud)


use*_*291 7

我同意,如果你只需要name价值观,那Set就是一种方法.

但是,如果您想根据name属性获取一组唯一对象,我建议使用Map.创建Map的一种快速方法是通过一组[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));
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { min-height: 100%; }
Run Code Online (Sandbox Code Playgroud)

另一个好处Map是,您既可以获得filter切断非独特的功能,又不会丢失与源对象的连接.当然,只有在需要多次引用唯一的对象集时才需要它.