循环嵌套数组并转换为对象

时间:2017-12-06 19:24:27

标签: javascript arrays loops multidimensional-array nested-loops

我想将一组嵌套数组转换为一个对象数组,其中包含来自嵌套数组的收集信息:

之前:

var employeeData = [
  [
    ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson']
  ],
  [
    ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director']
  ]
]

在:

[
  {firstName: 'Bob', lastName: 'Lob', age: 22, role: 'salesperson'},
  {firstName: 'Mary', lastName: 'Joe', age: 32, role: 'director'}
]

这是我为解决这个问题而编写的函数,但我不能完全看出循环出错的地方:



    var employeeData = [
      [
        ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson']
      ],
      [
        ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director']
      ]
    ]


    function transformData(employeeData) {
      let newObject = {};
      let newArr = [];
  
      for (var i = 0; i < employeeData.length; i++) { 
        for (var x = 0; x < employeeData[i].length; x++) { 
          for (var y = 0; y < employeeData[i][y].length; y++) { 
            newObject[employeeData[i][y][0]] = employeeData[i][y][1];
          } 
        }
        newArr.push(newObject);
        newObject = {};
      }
      return newArr;
    }
    
    console.log(transformData(employeeData));
&#13;
&#13;
&#13;

提前致谢。

7 个答案:

答案 0 :(得分:8)

您的代码出了什么问题:

第三级for循环搞砸了。它应该删除:

for (var y = 0; y < employeeData[i][x].length; y++) {
//                                  ^ by the way this should be x not y (not fixing the problem though)

因为第三级数组包含您需要同时使用的2个元素(作为键值),应删除<{1}}它们的循环

<强>修正:

for

修正代码示例:

for (var i = 0; i < employeeData.length; i++) { 
    for (var x = 0; x < employeeData[i].length; x++) { 
        newObject[employeeData[i][x][0]] = employeeData[i][x][1];
    }
    newArr.push(newObject);
    newObject = {};
}

替代解决方案:

你可以将var employeeData = [ [ ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson'] ], [ ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director'] ] ] function transformData(employeeData) { let newObject = {}; let newArr = []; for (var i = 0; i < employeeData.length; i++) { for (var x = 0; x < employeeData[i].length; x++) { newObject[employeeData[i][x][0]] = employeeData[i][x][1]; } newArr.push(newObject); newObject = {}; } return newArr; } console.log(transformData(employeeData)); map数组放入一个新数组中,employeeData将每个子数组放入一个这样的对象中:

reduce

可以使用ES6的箭头功能将其缩短为:

var result = employeeData.map(function(sub) {
    return sub.reduce(function(obj, pair) {
        obj[ pair[0] ] = pair[1];
        return obj;
    }, {});
});

示例:

let result = employeeData.map(sub => sub.reduce((obj, pair) => (obj[pair[0]] = pair[1], obj), {}));

答案 1 :(得分:4)

如何修复代码

你只需要2个for循环: 1.迭代数组 2.迭代子数组并构造对象

var employeeData = [[["firstName","Bob"],["lastName","Lob"],["age",22],["role","salesperson"]],[["firstName","Mary"],["lastName","Joe"],["age",32],["role","director"]]]

function transformData(employeeData) {
  let newObject;
  const newArr = [];

  for (var i = 0; i < employeeData.length; i++) {
    newObject = {}; // init new object
    for (var x = 0; x < employeeData[i].length; x++) {
        newObject[employeeData[i][x][0]] = employeeData[i][x][1]; // iterate inner arrays and assign properties to object
    }
    newArr.push(newObject);
  }
  return newArr;
}

console.log(transformData(employeeData));

另一种选择是使用Array#map的组合来迭代外部数组,使用Array#reduce来构造内部数组中的对象:

const employeeData = [[["firstName","Bob"],["lastName","Lob"],["age",22],["role","salesperson"]],[["firstName","Mary"],["lastName","Joe"],["age",32],["role","director"]]]

const result = employeeData.map((arr) => 
  arr.reduce((o, [key, value]) => (o[key] = value, o), {})
);

console.log(result);

答案 2 :(得分:1)

问题是你使用变量x和y

首先,有一行

for (var y = 0; y < employeeData[i][y].length; y++)

也许你的意思是使用employeeData[i][x].length,因为正如你在这里所说的那样,它会表现得非常奇怪。

但是,如果将y替换为变量x,则可以完全取消它(在您的实现中甚至从未使用过它)

以下是我对您的功能的建议编辑:

function transformData(employeeData) {
  let newObject = {}; 
  let newArr = []; 

  for (var i = 0; i < employeeData.length; i++) { 
    for (var x = 0; x < employeeData[i].length; x++) { 
      newObject[employeeData[i][x][0]] = employeeData[i][x][1];
    }   
    newArr.push(newObject);
    newObject = {}; 
  }
  return newArr;
}

使用这些更改运行示例我得到了正确的输出:

[
  {
    firstName: 'Bob',
    lastName: 'Lob',
    age: 22,
    role: 'salesperson'
  },
  {
    firstName: 'Mary',
    lastName: 'Joe',
    age: 32,
    role: 'director'
  }
]

答案 3 :(得分:1)

如果您正确使用索引,可以使用for循环解决您遇到的问题。 如果您像我一样格式化数据,您将看到索引有三个级别[i,x,y];

例如对于employeeData [0]你应该得到:

[
    ['firstName', 'Bob'],
    ['lastName', 'Lob'],
    ['age', 22],
    ['role', 'salesperson']
  ]

然后对于employeeData [0] [0]你应该得到:

 ['firstName', 'Bob']

对于employeeData [0] [0] [0],你应该得到:'firstName'

要访问'Bob',您需要employeeData [0] [0] [1],因为您知道此内部数组中只有两个元素,您不需要循环它。 正如@TallChuck所说,你问题的很大一部分源于忘记使用x索引。

var employeeData = [
  [
    ['firstName', 'Bob'],
    ['lastName', 'Lob'],
    ['age', 22],
    ['role', 'salesperson']
  ],
  [
    ['firstName', 'Mary'],
    ['lastName', 'Joe'],
    ['age', 32],
    ['role', 'director']
  ]
]


function transformData(employeeData) {
  let newObject = {};
  let newArr = [];

  for (var i = 0; i < employeeData.length; i++) {
    for (var x = 0; x < employeeData[i].length; x++) {
      newObject[employeeData[i][x][0]] = employeeData[i][x][1];
    }
    newArr.push(newObject);
    newObject = {};
  }
  return newArr;
}

console.log(transformData(employeeData));

修改

如果您注意索引,也可以制作一些更复杂的解决方案。假设您有以下数据:

var employeeData = [
  [
    ['firstName', 'Bob', 'weight', '80kg'],
    ['lastName', 'Lob'],
    ['age', 22],
    ['role', 'salesperson']
  ],
  [
    ['firstName', 'Mary', 'eye color', 'green'],
    ['lastName', 'Joe'],
    ['age', 32],
    ['role', 'director']
  ]
]

然后我给出的解决方案不会直接工作。但仔细观察,您会发现在某些数组中,您的字段名称位于 Y 索引的位置0,2。这意味着您的字段名称位于一对位置,而字段值位于奇数位置。因此,您实际上可以通过y进行循环,并检查Y索引是否可以被2整除。

if(y % 2 == 0 ..){}

只有当有一个伴随的奇数值时才这样做

if(y % 2 == 0 && employeeData[i][x][y+1]){..}

完整的代码如下。

var employeeData = [
  [
    ['firstName', 'Bob', 'weight', '80kg'],
    ['lastName', 'Lob'],
    ['age', 22],
    ['role', 'salesperson']
  ],
  [
    ['firstName', 'Mary', 'eye color', 'green'],
    ['lastName', 'Joe'],
    ['age', 32],
    ['role', 'director']
  ]
]


function transformData(employeeData) {
  let newObject = {};
  let newArr = [];

  for (var i = 0; i < employeeData.length; i++) {
    for (var x = 0; x < employeeData[i].length; x++) {
      for (var y = 0; y < employeeData[i][x].length; y++) {
        if(y % 2 == 0 && employeeData[i][x][y+1]){
          newObject[employeeData[i][x][y]] = employeeData[i][x][y+1];
        }
      }
    }
    newArr.push(newObject);
    newObject = {};
  }
  return newArr;
}

console.log(transformData(employeeData));

答案 4 :(得分:0)

您可能只想对外部数组中的每组值使用SELECT posts_podukter.post_title AS podukter_post_title, podukter_meta_produkter_0_pris_tbl.meta_value AS podukter_meta_produkter_0_pris FROM beta_h3L_posts AS posts_podukter INNER JOIN (SELECT podukter_meta_produkter_0_pris_tbl_posts.ID as id, meta_value, meta_key FROM beta_h3L_postmeta AS podukter_meta_produkter_0_pris_tbl_postmeta INNER JOIN beta_h3L_posts AS podukter_meta_produkter_0_pris_tbl_posts ON podukter_meta_produkter_0_pris_tbl_postmeta.post_id = podukter_meta_produkter_0_pris_tbl_posts.ID AND podukter_meta_produkter_0_pris_tbl_posts.post_type = 'podukter') AS podukter_meta_produkter_0_pris_tbl ON podukter_meta_produkter_0_pris_tbl.meta_key = 'produkter_0_pris' AND podukter_meta_produkter_0_pris_tbl.id = posts_podukter.ID WHERE 1=1 AND posts_podukter.post_type = 'podukter' 而不是Map

然后它是Object的非常简单的转换。地图已添加到这些数据集的规范中。

&#13;
&#13;
new Map(data);
&#13;
&#13;
&#13;

但如果你最终想要数组中的var employeeData = [ [['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson']], [['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director']] ]; const res = employeeData.map(a => new Map(a)); for (const m of res) { console.log(m.get("firstName")); }类型,那么你可以转换每个Object

&#13;
&#13;
Map()
&#13;
&#13;
&#13;

答案 5 :(得分:0)

使用map和reduce可以轻松完成

actingAs

答案 6 :(得分:-1)

其他人已经指出如何使用map数组函数可以简化您的任务,这些都是很好的解决方案(比计算循环要好得多),但它们并没有解决您实际提出的问题。

您的代码实际上运行正常,您只是没有提取所有可用的数据。你只有名字和姓氏。通过再添加两行,您可以获得其余数据。此外,第二个循环甚至没有必要(它不会伤害你,但它实际上并没有帮助,因为你从来没有在任何地方使用x计数器。)

&#13;
&#13;
var employeeData = [
      [
        ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson']
      ],
      [
        ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director']
      ]
    ]


    function transformData(employeeData) {
      let newObject = {};
      let newArr = [];
  
      for (var i = 0; i < employeeData.length; i++) { 

          for (var y = 0; y < employeeData[i][y].length; y++) { 
            newObject[employeeData[i][y][0]] = employeeData[i][y][1];
            
            // Now you have to get the next two array elements as well:
            newObject[employeeData[i][y+1][0]] = employeeData[i][y+1][1];
            newObject[employeeData[i][y+2][0]] = employeeData[i][y+2][1];            
          } 
 
        newArr.push(newObject);
        newObject = {};
      }
      return newArr;
    }
    
    console.log(transformData(employeeData));
&#13;
&#13;
&#13;