使用Javascript在嵌套对象中创建对象数组

使用Javascript在嵌套对象中创建对象数组,javascript,Javascript,给定以下javascript对象结构,这通常是 你将如何将其转换为 [ { 'fname' : 'value', 'lname' : 'value, 'things' : [ { 'brand' : 'value', 'name' : 'value' }, { 'brand' : 'value', 'name' : 'value' }, {

给定以下javascript对象结构,这通常是

你将如何将其转换为

[
  {
    'fname' : 'value',
    'lname' : 'value,
    'things' : [
      {
        'brand' : 'value',
        'name' : 'value'
      },
      {
        'brand' : 'value',
        'name' : 'value'
      },
      {
        'brand' : 'value',
        'name' : 'value'
      }
    ]
  },
  {
    'fname' : 'value',
    'lname' : 'value,
    'things' : [
      {
        'brand' : 'value',
        'name' : 'value'
      },
      {
        'brand' : 'value',
        'name' : 'value'
      },
      {
        'brand' : 'value',
        'name' : 'value'
      }
    ]
  }
]
请记住,嵌套对象可能会比这更深。有许多实现可以将嵌套结构转换为数组,但我还没有看到任何人进行这种特定的转换。我绞尽脑汁已经有一段时间了,只差一点点就想好了,但还没想好

我已经有了这段代码,它不能处理像“things”这样的深层对象

var collection = [];
for(key in data) {
  collection.push(data[key]);
}
我正在努力使它递归

编辑 我可以想象它需要包装在一个可以调用自身的函数中,这样它就可以进行递归。

var newData=[];
var dataKeys=Object.keys(数据);

对于(var i=0;i这样的东西应该可以做到:

function convert(object, propNamesToConvert) {
  var array = [];
  Object.keys(object).forEach(function(key) {
    array.push(visit(object[key], propNamesToConvert));
  });
  return array;
}

function visit(object, propNamesToConvert) {
  var result = {};
  Object.keys(object).forEach(function(key) {
    var value = object[key];
    if (typeof(value) === 'object') {
      // objects are either 'things to be converted' or we need to traverse further down the rabbit hole
      if (propNamesToConvert.indexOf(key) >= 0) {
        value = convert(value, propNamesToConvert);
      }
      else {
        value = visit(value, propNamesToConvert);
      }
    }
    result[key] = value;
  });
  return result;
}

console.log(JSON.stringify(visit(data, ['things'])));
它可能会被大大缩短,但这是有效的。将硬编码的
['things']
翻译成不太容易维护的东西会更好

var数据={
“id1”:{
“fname”:“value”,
“lname”:“value”,
“事情”:{
“事情1”:{
‘品牌’:‘价值’,
“名称”:“值”
},
“事情2”:{
‘品牌’:‘价值’,
“名称”:“值”
},
“事情3”:{
‘品牌’:‘价值’,
“名称”:“值”
}
}
},
“id2”:{
“fname”:“value”,
“lname”:“value”,
“事情”:{
“事情1”:{
‘品牌’:‘价值’,
“名称”:“值”
},
“事情2”:{
‘品牌’:‘价值’,
“名称”:“值”
},
“事情3”:{
‘品牌’:‘价值’,
“名称”:“值”
}
}
}
};
函数转换(对象、propNamesToConvert){
var数组=[];
Object.keys(对象).forEach(函数(键){
push(访问(object[key],propNamesToConvert));
});
返回数组;
}
功能访问(对象、propNamesToConvert){
var result={};
Object.keys(对象).forEach(函数(键){
var值=对象[键];
if(类型(值)=“对象”){
if(propNamesToConvert.indexOf(key)>=0){
值=转换(值,propNamesToConvert);
}
否则{
价值=访问(价值,propNamesToConvert);
}
}
结果[键]=值;
});
返回结果;
}
console.log(JSON.stringify(访问(数据,['things'));

这里有一个不需要知道密钥的解决方案,假设您希望每隔一个嵌套级别转换一次:

function toArrayOfObjects(obj) {
  var collection = [];
  for (key in obj) {
    var value = obj[key];
    if (typeof value === 'object' && !Array.isArray(value)) {
      var childObj = {};
      for (childKey in value) {
        var childValue = value[childKey];
        if (typeof childValue === 'object' && !Array.isArray(childValue)) {
          childObj[childKey] = toArrayOfObjects(childValue);
        } else {
          childObj[childKey] = childValue;
        }
      }
      collection.push(childObj);
    } else {
      collection.push(value);
    }
  }
  return collection;
}

这不考虑像“东西”这样的更深层次的对象。可能是@FrankvanPuffelen的重复。这不是它的重复。我已经有了那个代码。我正在寻找它更深入,并在对象的所有层次上迭代。你链接到的问题和答案正在做我已经在做的事情。关闭投票撤回,下面回答。键名是否应表示数组顺序?例如(id1、id2/thing1 thing2)如果是,规则是什么?@LukeP键不表示排序。对象在设置为数据变量之前在服务器上排序。谢谢Frank。Brent的解决方案,我将选择作为答案的解决方案不需要了解键。听起来不错。请记住,这两种解决方案都假设了您的数据结构(一个是隐式假设,另一个是显式假设)。这样的选择是必要的,因为您处理的是无模式模型,因此JSON数据本身不清楚需要将哪个级别展平为数组。
function toArrayOfObjects(obj) {
  var collection = [];
  for (key in obj) {
    var value = obj[key];
    if (typeof value === 'object' && !Array.isArray(value)) {
      var childObj = {};
      for (childKey in value) {
        var childValue = value[childKey];
        if (typeof childValue === 'object' && !Array.isArray(childValue)) {
          childObj[childKey] = toArrayOfObjects(childValue);
        } else {
          childObj[childKey] = childValue;
        }
      }
      collection.push(childObj);
    } else {
      collection.push(value);
    }
  }
  return collection;
}