如何从JavaScript中的对象数组中获取不同的值?



Answers

如果您使用的是ES6 / ES2015或更高版本,则可以这样做:

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

Here是一个如何做到Here一点的例子。

基于@Jonas Kello编辑建议:

const unique = [...new Set(array.map(item => item.age))];
Question

假设我有以下几点:

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)



如果你有Array.prototype.includes或愿意polyfill它,这可以工作:

var ages = []; array.forEach(function(x) { if (!ages.includes(x.age)) ages.push(x.age); });



使用ES6功能,您可以执行如下操作:

const uniqueAges = [...new Set( array.map(obj => obj.age)) ];



unique(obj, prop) {
    let result = [];
    let seen = new Set();

    Object.keys(obj)
        .forEach((key) => {
            let value = obj[key];

            let test = !prop
                ? value
                : value[prop];

            !seen.has(test)
                && seen.add(test)
                && result.push(value);
        });

    return result;
}



forEach版本的@travis-j的答案(对现代浏览器和Node JS世界有帮助):

var unique = {};
var distinct = [];
array.forEach(function (x) {
  if (!unique[x.age]) {
    distinct.push(x.age);
    unique[x.age] = true;
  }
});

Chrome v29.0.1547上的速度提高了34%: http://jsperf.com/filter-versus-dictionary/3 ://jsperf.com/filter-versus-dictionary/3

还有一个采用mapper函数的通用解决方案(比直接映射慢,但是这是预期的):

function uniqueBy(arr, fn) {
  var unique = {};
  var distinct = [];
  arr.forEach(function (x) {
    var key = fn(x);
    if (!unique[key]) {
      distinct.push(key);
      unique[key] = true;
    }
  });
  return distinct;
}

// usage
uniqueBy(array, function(x){return x.age;}); // outputs [17, 35]



你试一试

var x = [] ;
for (var i = 0 ; i < array.length ; i++)
{
 if(x.indexOf(array[i]['age']) == -1)
  {
    x.push(array[i]['age']);
  }
}
console.log(x);



underscore.js _.uniq(_.pluck(array,"age"))




使用ES6

let array = [
  { "name": "Joe", "age": 17 },
  { "name": "Bob", "age": 17 },
  { "name": "Carl", "age": 35 }
];
array.map(item => item.age)
  .filter((value, index, self) => self.indexOf(value) === index)

> [17, 35]



我在这个功能上的两分钱:

var result = [];
for (var len = array.length, i = 0; i < len; ++i) {
  var age = array[i].age;
  if (result.indexOf(age) > -1) continue;
  result.push(age);
}

你可以在这里看到结果(方法8) http://jsperf.com/distinct-values-from-array/3




刚刚发现这一点,我认为它很有用

_.map(_.indexBy(records, '_id'), function(obj){return obj})

再次使用underscore ,所以如果你有这样的对象

var records = [{_id:1,name:'one', _id:2,name:'two', _id:1,name:'one'}]

它只会给你唯一的对象。

这里发生的是indexBy像这样返回一张地图

{ 1:{_id:1,name:'one'}, 2:{_id:2,name:'two'} }

只是因为它是一张地图,所有的钥匙都是独一无二的。

然后我只是将这个列表映射回数组。

如果你只需要不同的值

_.map(_.indexBy(records, '_id'), function(obj,key){return key})

请记住, key是以字符串的形式返回的,所以如果你需要整数,你应该这样做

_.map(_.indexBy(records, '_id'), function(obj,key){return parseInt(key)})



function get_unique_values_from_array_object(array,property){
    var unique = {};
    var distinct = [];
    for( var i in array ){
       if( typeof(unique[array[i][property]]) == "undefined"){
          distinct.push(array[i]);
       }
       unique[array[i][property]] = 0;
    }
    return distinct;
}



使用Lodash

var array = [
    { "name": "Joe", "age": 17 },
    { "name": "Bob", "age": 17 },
    { "name": "Carl", "age": 35 }
];
_.chain(array).pluck('age').unique().value();
> [17, 35]





Links