使用包含多个对象的单个索引遍历数组

时间:2020-03-27 05:18:33

标签: javascript arrays json object

我有一些看起来像这样的数据

    <select value={formState.size} name='size' id='sizeinput' onChange={inputChange}>
        <option value={null} disabled>Select</option>
        <option value='Sm'>Sm</option>
        <option value='Lg'>Lg</option>
        <option value='XL'>XL</option>
    </select>

我想像这样重新格式化

let arr = [
  {
    a:1,
    b:2,
    c:3
  },
  {
    a:4,
    b:5,
    c:6
  },
  {
    a:7,
    b:8,
    c:9
  }
]

这是我的解决方案:

{
   a: [1,4,7],
   b: [2,5,8],
   c: [3,6,9]
}

我知道我的解决方案不是最有效的方法。在完成练习时,我无法理解以下概念:

  • 乍看之下,let arr = [ { a:1, b:2, c:3 }, { a:4, b:5, c:6 }, { a:7, b:8, c:9 } ] // { // a: [1,4,7], // b: [2,5,8], // c: [3,6,9] // } function practice (arr) { console.log(typeof arr) // WHY IS THIS RETURNING AN OBJECT??? let keys = Object.keys(arr[0]) const resultObj = {} for (let key of keys) { resultObj[key] = [] } arr.forEach((x,idx)=> { for (let key in x) { resultObj[key].push(x[key]) } }) return resultObj } practice(arr) 对我来说似乎是具有单个索引的数组 包含三个对象。例如,arr,但是 我对arr[0] = {obj1},{obj2},{obj3}进行了typeof检查,并返回了对象。
  • 当我在指定的索引arr上控制台日志arr时,它会像打印出一个数组一样打印出arr[1]
  • 我的问题是这里发生了什么,这种数据结构到底是什么?

请为我提供一个更干净有效的代码,并向我解释概念。

5 个答案:

答案 0 :(得分:1)

尝试

function practice (arr) {
  let resultObj = {};

  arr.forEach((x) => {
    for (let key in x) {
      if (resultObj.hasOwnProperty(key)) {
        resultObj[key].push(x[key]);
      } else {
        resultObj[key] = [x[key]];
      }
    }
  });

  return resultObj;
}

答案 1 :(得分:1)

为了检查数组,您应该使用Array.isArray()方法。 typeof将为您提供一个对象,因为Array本质上是使用Object构造函数创建的javascript对象的一种形式。

要获得所需的输出,您需要做的就是遍历数组并将值存储在对象中

let arr = [
  {
    a:1,
    b:2,
    c:3
  },
  {
    a:4,
    b:5,
    c:6
  },
  {
    a:7,
    b:8,
    c:9
  }
]

var res = {};
arr.forEach((obj) => {
   Object.entries(obj).forEach(([key, val]) => {
      if(res[key]) {
         res[key].push(val);
      } else {
         res[key] = [val];
      }
   })
});

console.log(res);

答案 2 :(得分:1)

您可以使用数组reduce()方法,例如:

  • Object.keys(o)方法内使用reduce()遍历数组中每个对象的所有键
  • 在循环内部,使用与循环内相同的键来初始化累加器,并将该键的初始值为空数组[]
  • 然后使用r[k].push(o[k])在此数组中添加匹配的键值。
  • 然后最后从r方法返回对象.reduce()

let arr = [{a:1,b:2,c:3},{a:4,b:5,c:6},{a:7,b:8,c:9}];
const res = arr.reduce((r, o) => {
  Object.keys(o).forEach((k) => {
    r[k] = r[k] || [];
    r[k].push(o[k])
  });
  return r;
}, {})

console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 3 :(得分:0)

您可以试试这个-

let arr = [
  {
    a:1,
    b:2,
    c:3
  },
  {
    a:4,
    b:5,
    c:6
  },
  {
    a:7,
    b:8,
    c:9
  }
];

let res = {};

Object.values(arr).forEach(value => {
  Object.keys(value).forEach(key => {
   if (typeof res[key] === 'undefined') {
     res[key] = [];
   }
   res[key].push(value[key])
  })
})


console.log(res);

答案 4 :(得分:0)

使用多个forEach循环构建具有键的对象,并将值合并为同一键。

let arr = [
  {
    a: 1,
    b: 2,
    c: 3
  },
  {
    a: 4,
    b: 5,
    c: 6
  },
  {
    a: 7,
    b: 8,
    c: 9
  }
];

const res = {};
arr.forEach(item => {
  Object.keys(item).forEach(
    key => (res[key] = key in res ? [...res[key], item[key]] : [item[key]])
  );
});

console.log(res);