从对象数组中获取所有唯一对象属性

时间:2021-07-31 20:15:15

Let's imagine I have an array of objects e.g.

让我们想象一下我有一系列对象,例如:

 [{
    "firstName": "John",
    "lastName": "Doe"
 }, {
    "firstName": "Anna",
    "car": true
 }, {
    "firstName": "Peter",
    "lastName": "Jones"
 }]

I want to get all the unique property names from this array of objects, so the result will be:

我想从这个对象数组中获取所有唯一的属性名称,因此结果将是:

[firstName, lastName, car]

How can I do it:

我该怎么做:

I can imagine that it's possible to do this with something like this:

我可以想象用这样的东西可以做到这一点:

function getPropertiesNames(obj){
  var arr = [];
  for(var name in obj) {
    if(arr.indexOf(name) != -1) arr.push(name);
  }
 return arr;
} 

Why I need it:

为什么我需要它:

I will have to make a table of multiple objects. Because each object can be a bit different I need unique property names. However I am going to do it in angularJS so it's kind of a bad option for me to once use loop to get property names for <th> and once again use loop with <tr ng-repeat></tr> to display values.

我将不得不制作一个包含多个对象的表格。因为每个对象可能有点不同,所以我需要唯一的属性名称。但是我要在angularJS中这样做,所以对于我来说,一旦使用循环获取的属性名称并再次使用带有 的循环来显示值,这对我来说是一个糟糕的选择。

What i want:

我想要的是:

Is there some option to get all unique property names from an array of objects without iterating it? Maybe some lodash or build in JS function which I don't know?

是否有一些选项可以从一个对象数组中获取所有唯一属性名称而无需迭代它?也许一些lodash或构建JS功能,我不知道?

6 个解决方案

#1


12  

A solution using only:

仅使用的解决方案:

var data = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}];

var uniqueKeys = Object.keys(data.reduce(function(result, obj) {
  return Object.assign(result, obj);
}, {}))

console.log(uniqueKeys);

#2


4  

You could use map() and keys() to return keys of each object and then union() and flatten()

您可以使用map()和keys()返回每个对象的键,然后使用union()和flatten()

var data = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}]

var result = _.union(_.flatten(_.map(data, (e) => _.keys(e))));
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

#3


3  

I don't think you can get away from checking each key in each object. You could accomplish it with e.g reduce:

我不认为你可以远离检查每个对象中的每个键。您可以通过例如reduce来实现它:

var result = _.reduce(array, function(memory, obj) {
  for (var key in obj) {
    if(memory.indexOf(key) === -1) memory.push(key)
  }
  return memory;
}, []);

var array = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}];

var result = _.reduce(array, function(memory, obj) {
  for (var key in obj) {
    if(memory.indexOf(key) === -1) memory.push(key)
  }
  return memory;
}, []);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

Alternatively, you could store the keys in a new object, and just extract the keys:

或者,您可以将键存储在新对象中,然后只提取键:

var temp = _.reduce(array, function(memory, obj) {
  for (var key in obj) {
    memory[key] = null;
  }
  return memory;
}, {});
var result = Object.keys(temp);

var array = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}];

var temp = _.reduce(array, function(memory, obj) {
  for (var key in obj) {
    memory[key] = null;
  }
  return memory;
}, {});
var result = Object.keys(temp);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

#4


1  

You may also try this:

你也可以试试这个:

var source = [{
"firstName": "John",
"lastName": "Doe"
 }, {
"firstName": "Anna",
"car": true
 }, {
"firstName": "Peter",
"lastName": "Jones"
 }];

uniq(source);

function uniq(source){
   var result = source.reduce(function(p, c) {

     Object.keys(c).forEach(function(key) {
         p[key] = true;
     });

     return p;
    }, {});

    return Object.keys(result);
}

#5


1  

You can use this:

你可以用这个:

var result = [];
array.reduce( function(pre, item) {
    Object.keys(item).forEach(function(i){
        if (result.indexOf(i) === -1){
            result.push(i);
        }
    });
});

var array = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}];

var result = [];
array.reduce( function(pre, item) {
    Object.keys(item).forEach(function(i){
        if (result.indexOf(i) === -1){
            result.push(i);
        }
    });
});

console.log(result);

#6


1  

My solution without any library.

我的解决方案没有任何库。

var array = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}];

var arr = [],merged,uniqArray;

array.forEach(function(val){ //Getting all properties
   arr.push(Object.keys(val))
 });

merged = [].concat.apply([], arr);//Merging all array to single array

merged.forEach(function(val){
  if(uniqArray.indexOf(val)== -1){// Getting uniqe values
   uniqArray.push(val)
}})

RESULT

结果

["firstName", "lastName", "car"]

#1


12  

A solution using only:

仅使用的解决方案:

var data = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}];

var uniqueKeys = Object.keys(data.reduce(function(result, obj) {
  return Object.assign(result, obj);
}, {}))

console.log(uniqueKeys);

#2


4  

You could use map() and keys() to return keys of each object and then union() and flatten()

您可以使用map()和keys()返回每个对象的键,然后使用union()和flatten()

var data = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}]

var result = _.union(_.flatten(_.map(data, (e) => _.keys(e))));
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

#3


3  

I don't think you can get away from checking each key in each object. You could accomplish it with e.g reduce:

我不认为你可以远离检查每个对象中的每个键。您可以通过例如reduce来实现它:

var result = _.reduce(array, function(memory, obj) {
  for (var key in obj) {
    if(memory.indexOf(key) === -1) memory.push(key)
  }
  return memory;
}, []);

var array = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}];

var result = _.reduce(array, function(memory, obj) {
  for (var key in obj) {
    if(memory.indexOf(key) === -1) memory.push(key)
  }
  return memory;
}, []);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

Alternatively, you could store the keys in a new object, and just extract the keys:

或者,您可以将键存储在新对象中,然后只提取键:

var temp = _.reduce(array, function(memory, obj) {
  for (var key in obj) {
    memory[key] = null;
  }
  return memory;
}, {});
var result = Object.keys(temp);

var array = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}];

var temp = _.reduce(array, function(memory, obj) {
  for (var key in obj) {
    memory[key] = null;
  }
  return memory;
}, {});
var result = Object.keys(temp);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

#4


1  

You may also try this:

你也可以试试这个:

var source = [{
"firstName": "John",
"lastName": "Doe"
 }, {
"firstName": "Anna",
"car": true
 }, {
"firstName": "Peter",
"lastName": "Jones"
 }];

uniq(source);

function uniq(source){
   var result = source.reduce(function(p, c) {

     Object.keys(c).forEach(function(key) {
         p[key] = true;
     });

     return p;
    }, {});

    return Object.keys(result);
}

#5


1  

You can use this:

你可以用这个:

var result = [];
array.reduce( function(pre, item) {
    Object.keys(item).forEach(function(i){
        if (result.indexOf(i) === -1){
            result.push(i);
        }
    });
});

var array = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}];

var result = [];
array.reduce( function(pre, item) {
    Object.keys(item).forEach(function(i){
        if (result.indexOf(i) === -1){
            result.push(i);
        }
    });
});

console.log(result);

#6


1  

My solution without any library.

我的解决方案没有任何库。

var array = [{
  "firstName": "John",
  "lastName": "Doe"
}, {
  "firstName": "Anna",
  "car": true
}, {
  "firstName": "Peter",
  "lastName": "Jones"
}];

var arr = [],merged,uniqArray;

array.forEach(function(val){ //Getting all properties
   arr.push(Object.keys(val))
 });

merged = [].concat.apply([], arr);//Merging all array to single array

merged.forEach(function(val){
  if(uniqArray.indexOf(val)== -1){// Getting uniqe values
   uniqArray.push(val)
}})

RESULT

结果

["firstName", "lastName", "car"]