How to get distinct values from an array of object

2019-01-01 08:08发布

Assuming I have the following:

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

What is the best way to be able to get an array of all of the distinct ages such that I get an result array of:

[17, 35]

Is there some way I could alternatively structure the data or better method such that I would not have to iterate through each array checking the value of "age" and check against another array for its existence, and add it if not?

If there was some way I could just pull out the distinct ages without iterating...

Current inefficent way I would like to improve... If it means that instead of "array" being an array of objects, but a "map" of objects with some unique key (i.e. "1,2,3") that would be okay too. Im just looking for the most performance efficient way.

The following is how I currently do it, but for me, iteration appears to just be crummy for efficiency even though it does work...

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

27条回答
十年一品温如言
2楼-- · 2019-01-01 08:43

using lodash

var array = [
    { "name": "Joe", "age": 17 },
    { "name": "Bob", "age": 17 },
    { "name": "Carl", "age": 35 }
];
_.chain(array).pluck('age').unique().value();
> [17, 35]
查看更多
伤终究还是伤i
3楼-- · 2019-01-01 08:45
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;
}
查看更多
看风景的人
4楼-- · 2019-01-01 08:47

I've started sticking Underscore in all new projects by default just so I never have to think about these little data-munging problems.

var array = [{"name":"Joe", "age":17}, {"name":"Bob", "age":17}, {"name":"Carl", "age": 35}];
console.log(_.chain(array).map(function(item) { return item.age }).uniq().value());

Produces [17, 35].

查看更多
不再属于我。
5楼-- · 2019-01-01 08:49
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;
}
查看更多
临风纵饮
6楼-- · 2019-01-01 08:50

this is how you would solve this using new Set via ES6 for Typescript as of August 25th, 2017

Array.from(new Set(yourArray.map((item: any) => item.id)))
查看更多
姐姐魅力值爆表
7楼-- · 2019-01-01 08:52

You could use a dictionary approach like this one. Basically you assign the value you want to be distinct as the key in a dictionary. If the key did not exist then you add that value as distinct.

var unique = {};
var distinct = [];
for( var i in array ){
 if( typeof(unique[array[i].age]) == "undefined"){
  distinct.push(array[i].age);
 }
 unique[array[i].age] = 0;
}

Here is a working demo: http://jsfiddle.net/jbUKP/1

This will be O(n) where n is the number of objects in array and m is the number of unique values. There is no faster way than O(n) because you must inspect each value at least once.

Performance

http://jsperf.com/filter-versus-dictionary When I ran this dictionary was 30% faster.

查看更多
登录 后发表回答