假设我有以下内容:

var array = 
    [
        {"name":"Joe", "age":17}, 
        {"name":"Bob", "age":17}, 
        {"name":"Carl", "age": 35}
    ]

获得所有不同年龄的数组的最佳方法是什么,这样我就得到了一个结果数组:

[17, 35]

是否有一些方法,我可以选择结构数据或更好的方法,这样我就不必遍历每个数组检查“年龄”的值,并检查另一个数组是否存在,如果没有添加它?

如果有某种方法可以让我不用迭代就能得到不同的年龄……

目前效率低下的方式,我想改进…如果它的意思不是“数组”是一个对象的数组,而是一个对象的“映射”与一些唯一的键(即。"1,2,3")也可以。我只是在寻找最高效的方式。

以下是我目前的做法,但对我来说,迭代似乎只是为了提高效率,即使它确实有效……

var distinct = []
for (var i = 0; i < array.length; i++)
   if (array[i].age not in distinct)
      distinct.push(array[i].age)

当前回答

var unique = array
    .map(p => p.age)
    .filter((age, index, arr) => arr.indexOf(age) == index)
    .sort(); // sorting is optional

// or in ES6

var unique = [...new Set(array.map(p => p.age))];

// or with lodash

var unique = _.uniq(_.map(array, 'age'));

ES6例子

const data = [
  { name: "Joe", age: 17}, 
  { name: "Bob", age: 17}, 
  { name: "Carl", age: 35}
];

const arr = data.map(p => p.age); // [17, 17, 35]
const s = new Set(arr); // {17, 35} a set removes duplications, but it's still a set
const unique = [...s]; // [17, 35] Use the spread operator to transform a set into an Array
// or use Array.from to transform a set into an array
const unique2 = Array.from(s); // [17, 35]

其他回答

[...new Set([
    { "name": "Joe", "age": 17 },
    { "name": "Bob", "age": 17 },
    { "name": "Carl", "age": 35 }
  ].map(({ age }) => age))]

我选取了随机样本,并将其与10万个项目进行了测试,如下所示:

let array=[]
for (var i=1;i<100000;i++){

 let j= Math.floor(Math.random() * i) + 1
  array.push({"name":"Joe"+j, "age":j})
}

这里是每一个的性能结果:

  Vlad Bezden Time:         === > 15ms
  Travis J Time: 25ms       === > 25ms 
  Niet the Dark Absol Time: === > 30ms
  Arun Saini Time:          === > 31ms
  Mrchief Time:             === > 54ms
  Ivan Nosov Time:          === > 14374ms

另外,我想提的是,由于项目是随机生成的,第二名是在Travis和Niet之间迭代。

使用新的Ecma功能很棒,但并不是所有用户都有这些功能。

下面的代码将附加一个名为distinct的新函数到Global Array对象。 如果您试图获取对象数组的不同值,则可以传递值的名称以获取该类型的不同值。

Array.prototype.distinct = function(item){   var results = [];
for (var i = 0, l = this.length; i < l; i++)
    if (!item){
        if (results.indexOf(this[i]) === -1)
            results.push(this[i]);
        } else {
        if (results.indexOf(this[i][item]) === -1)
            results.push(this[i][item]);
    }
return results;};

请查看我在CodePen中发布的演示。

高效和干净的方法,使用iter-ops库:

import {pipe, distinct, map} from 'iter-ops';

const array = 
    [
        {name: 'Joe', age: 17}, 
        {name: 'Bob', age: 17}, 
        {name: 'Carl', age: 35}
    ];

const i = pipe(
    array,
    distinct(a => a.age),
    map(m => m.age)
);

const uniqueAges = [...i]; //=> [17, 35]

回答这个老问题是毫无意义的,但是有一个简单的答案说明了Javascript的本质。Javascript中的对象本质上是哈希表。我们可以使用它来获得唯一键的哈希值:

var o = {}; array.map(function(v){ o[v.age] = 1; });

然后我们可以将哈希化简为一个唯一值的数组:

var a2 = []; for (k in o){ a2.push(k); }

这就是你所需要的。数组a2只包含唯一的年龄。