简体   繁体   English

如何在Javascript中从二维数组创建一个对象数组?

[英]How to create an array of objects from a 2d array in Javascript?

This is analogous to my actual problem but i feel illustrates the problem i need to solve without complicating things. 这类似于我的实际问题,但我觉得说明我需要解决的问题,而不会使事情复杂化。

I need to create an array of objects by iterating through a 2d array. 我需要通过迭代2d数组来创建一个对象数组。 The 2d array looks something like the"sampleArray" below. 2d数组看起来像下面的“sampleArray”。

let sampleArray = [ 
  ["open",2], 
  ["high",3], 
  ["low",5], 
  ["close", 10], 
  ["volume", 20], 
  ["open",20], 
  ["high",30], 
  ["low",50], 
  ["close", 100], 
  ["volume", 21],
  ["open",21], 
  ["high",33], 
  ["low",51], 
  ["close", 1], 
  ["volume", 2],
  ["open",7], 
  ["high",8], 
  ["low",5], 
  ["close", 11], 
  ["volume", 22]
 ];

I'm currently formatting a particularly ugly set of API data and have flattened the data down to a 2d array. 我目前正在格式化一组特别丑陋的API数据,并将数据展平为二维数组。 What i need now is to put these values into an array of 5 objects where each object's data property is populated by all of the values with that particular label. 我现在需要的是将这些值放入一个包含5个对象的数组中,其中每个对象的数据属性由具有该特定标签的所有值填充。

newObject = [
    {
     data: [2,20,21, ...]
     label: "open"  
    }, 
    {
     data: [3,50, ...]
     label: "high"
    }, 
    {
     data: [etc...]
     label: "low"  
    }, 
    {
     data: [etc...]
     label: "close"  
     }, 
    {
     data: [etc...]
     label: "volume"  
     }
]

I'm about 3 hours into trying to make this work and feel that I'm going about this all wrong, I keep getting an error that newArray[i]["label"] is undefined, I get why it's happening (no object with that property exists YET, I'm just not sure how to express that idea (If the object with that label doesn't exist yet, create it and add that matching value to it's value property) in javascript. 我大约需要3个小时才能完成这项工作,并且觉得我这一切都错了,我不断得到一个错误,即newArray [i] [“label”]未定义,我明白为什么会发生这种情况(没有对象)该属性存在YET,我只是不确定如何表达这个想法(如果具有该标签的对象尚不存在,创建它并将其匹配值添加到它的value属性)在javascript中。

function makeArray(array) {
  let newArray = [];
  for(let i = 0; i <= array.length; i++){
    if(newArray[i]["label"] !== array[i][0]){
      newArray.push({
        "label": array[i][0],
        "value": array[i][1]
      })
    }    
    else{
      newArray.push({
        "value": array[i][1]
      })
    }
  }
return newArray;
}

let test = makeArray(sampleArray);
console.log(test);

Sorry for the long post, I've been flattening this nightmare API all day and feel like I'm just running in place at this point. 很抱歉这篇长篇文章,我整天都在讨论这个噩梦API,觉得我现在只是跑到位。 I would much prefer a point in the right direction than an outright answer. 我更倾向于在正确的方向上找到一个点,而不是直接的答案。 I'm gonna hit the sack and see if someone can provide me with a little perspective by morning. 我要打瞌睡,看看有人能在早上给我一点透视。 Thank you! 谢谢!

You can use reduce 你可以使用reduce

 let sampleArray = [ ["open", 2], ["high", 3], ["low", 5], ["close", 10], ["volume", 20], ["open", 20], ["high", 30], ["low", 50], ["close", 100], ["volume", 21], ["open", 21], ["high", 33], ["low", 51], ["close", 1], ["volume", 2], ["open", 7], ["high", 8], ["low", 5], ["close", 11], ["volume", 22] ]; let newObject = Object.values(sampleArray.reduce((c, [n, v]) => { c[n] = c[n] || {label: n,data: []}; c[n].data.push(v); return c; }, {})); console.log(newObject); 

Using Vanilla JS: 使用Vanilla JS:

 let sampleArray = [ ["open", 2], ["high", 3], ["low", 5], ["close", 10], ["volume", 20], ["open", 20], ["high", 30], ["low", 50], ["close", 100], ["volume", 21], ["open", 21], ["high", 33], ["low", 51], ["close", 1], ["volume", 2], ["open", 7], ["high", 8], ["low", 5], ["close", 11], ["volume", 22] ]; function transform(sampArr) { let obj = {}; // A map equivalent to store repeated value // Loop through each array within array sampArr.forEach(function(arr) { if (!obj[arr[0]]) { obj[arr[0]] = {}; // Instantiate the map the first time } if (!obj[arr[0]].data) { obj[arr[0]]["data"] = []; // First time instantiate the array } obj[arr[0]].data.push(arr[1]); // Push the repeated values }); // Create the structure you want return Object.keys(obj).map(function(key) { return { data: obj[key].data, label: key }; }); } console.log(transform(sampleArray)); 

You can introduce a temperary variable before going to final value as - 您可以在达到最终价值之前引入一个临时变量 -

const tempObject = sampleArray.reduce((acc, arr) => {
  if (acc.hasOwnProperty(arr[0]) {
    return acc[arr[0]].push(arr[1]);
  }
  return { ...acc, { [arr[0]]: [arr[1]] };
}), {});

Now tempObject will be - 现在tempObject将 -

{
  'open': [2, 20, 21, ...],
  'high': [3, 50, ...],
  'low': [etc, ...],
  'close': [etc, ...],
  'volume': [etc, ...]
}

Then you can eterate to above object as, 然后你就可以对上面的对象进行迭代,

const finalData = Object.keys(tempObject).map(key => (
  {
    data: tempObject[key],
    label: key
  }
);

Now finalData will be the desired object. 现在finalData将成为所需的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM