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

时间:2016-08-31 11:41:05

标签: javascript angularjs arrays object lodash

让我们假设我有一系列对象,例如

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

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

[firstName, lastName, car]

我该怎么做:

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

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

为什么我需要它:

我必须制作一个包含多个对象的表格。因为每个对象可能有点不同,我需要唯一的属性名称。但是我将在angularJS中执行此操作,因此对于我来说,使用循环获取<th>的属性名称并再次使用带有<tr ng-repeat></tr>的循环来显示值时,这是一个不错的选择。

我想要的是什么:

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

9 个答案:

答案 0 :(得分:13)

仅使用以下解决方案:

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);

答案 1 :(得分:4)

您可以使用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>

答案 2 :(得分:3)

我认为你不能远离检查每个对象中的每个键。您可以使用例如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>

或者,您可以将密钥存储在新对象中,只需提取密钥:

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>

答案 3 :(得分:1)

您可以使用:

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);

答案 4 :(得分:1)

你也可以试试这个:

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)

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"]

答案 6 :(得分:1)

您可以使用Object.assign()spread syntax将对象数组合并为单个对象。然后从合并的对象中获取密钥:

Object.keys(Object.assign({}, ...array)) 

这是一个片段:

const array = [{firstName:"John",lastName:"Doe"},{firstName:"Anna",car:true},{firstName:"Peter",lastName:"Jones"}],
      unique = Object.keys(Object.assign({}, ...array))

console.log(unique)


另一种选择是使用Object.keys作为flatMap的回调。这将返回 all 键的数组。然后,创建Set以获取唯一键,然后使用Array.from()将集合转换为数组。

const keys = input.flatMap(Object.keys),
      unique = Array.from(new Set(keys));

这是一个有效的代码段:

const input=[{firstName:"John",lastName:"Doe"},{firstName:"Anna",car:true},{firstName:"Peter",lastName:"Jones"}],
      unique = Array.from(new Set(input.flatMap(Object.keys)));

console.log(unique)

如果不支持flatMap,则可以使用

const keys = [].concat(...input.map(Object.keys)),

答案 7 :(得分:0)

一个班轮选项:

[...new Set(a.map(Object.keys).reduce((a, b) => a.concat(b)))];

答案 8 :(得分:0)

替代者

const arr = 
[{
    "firstName": "John",
    "lastName": "Doe"
 }, {
    "firstName": "Anna",
    "car": true
 }, {
    "firstName": "Peter",
    "lastName": "Jones"
 }].map(obj => Object.getOwnPropertyNames(obj)).flat()
const s = [...new Set(arr)]
console.log(s)