1

I currently use this code to reformat my json into the format I want:

  let input = {
      "Apples": {
        "Apples_pos1": 501.82,
        "Apples_pos2": 502.61,
        "Apples_pos3": 502.61,
        "Apples": 502.16,
      }
    };

    let output = Object.keys(input).reduce((acc, outerKey) => {
      for (let [key, value] of Object.entries(input[outerKey])) {
        acc.push([outerKey, value, key.split('_')[1] || key]);
      }
      return acc;
    }, []);

    console.log(output);
[
   [
      "Apples",
      501.82,
      "pos1"
   ],
   [
      "Apples",
      502.61,
      "pos2"
   ],
   [
      "Apples",
      502.61,
      "pos3"
   ],
   [
      "Apples",
      502.16,
      "Apples"
   ]
]

If my input instead looked like this:

let second_input = {
  "Apples": {
    "11-26-19": {
      "Apples_pos1": 501.82,
      "Apples_pos2": 502.61,
      "Apples_pos3": 502.61,
      "Apples": 502.16,
    }
  }
};

And this is my desired output:

[
   [
      "Apples",
      501.82,
      "pos1",
      "11-26-19"
   ],
   [
      "Apples",
      502.61,
      "pos2",
      "11-26-19"
   ],
   [
      "Apples",
      502.61,
      "pos3",
      "11-26-19"
   ],
   [
      "Apples",
      502.16,
      "Apples",
      "11-26-19"
   ]
]

How could I edit my old code to be able to produce this desired output?

Thanks.

1
  • Just write the logic for this new data, just like you did for the older one. What's the problem you're facing? Commented Jun 18, 2020 at 22:13

3 Answers 3

1

You need to go one more layer deep, because you're now iterating over a subarray.

Explanation of Approach: I kept the style of code you had used, by doing another for (let [key, value] of Object.entries(...)) call -- this way, your code continues to resemble what it was before. If you need to go another layer deep, just follow the same procedure again, and knowing what to do should be no problem. In this case, continuity of code is a good thing! In the code, notice our new vars, subkey and subvalue...

let output = Object.keys(input).reduce((acc, outerKey) => {
  for (let [key, value] of Object.entries(input[outerKey])) {
    for (let [subkey, subvalue] of Object.entries(input[outerKey][key])) {
        var goodsubkey = subkey.replace(/^outerKey + '_'/, '');
        acc.push([outerKey, subvalue, goodsubkey, key]);
    }
  }
  return acc;
}, []);

Also, your arr.split(_)[1] call was a bit unclear, and it certainly won't work on increasingly, longer keys. So, I replaced this naturally with arr.replace(/^outerKey + '_'/, '');, which will have that forward compatibility. For instance, this key would break on your old code: Apples_pos1_pos2, etc..

Made a fully, working demo. Output...

[["Apples", 501.82, "pos1", "11-26-19"], ["Apples", 502.61, "pos2", "11-26-19"], ["Apples", 502.61, "pos3", "11-26-19"], ["Apples", 502.16, "Apples", "11-26-19"]]
Sign up to request clarification or add additional context in comments.

Comments

1

My try for this task, just modified the script a bit:

  let input = {
     "Apples": {
        "11-26-19": {
          "Apples_pos1": 501.82,
          "Apples_pos2": 502.61,
          "Apples_pos3": 502.61,
          "Apples": 502.16,
        }
      }
    };

    let output = Object.keys(input).reduce((acc, outerKey) => {
       Object.entries(input[outerKey]).forEach(([date, item]) => {
          for (let [key, value] of Object.entries(item)) {
            acc.push([outerKey, value, key.split('_')[1] || key, date]);
          }
       });
      return acc;
    }, []);

    console.log(output);

Output:

[
  [
    "Apples",
    501.82,
    "pos1",
    "11-26-19"
  ],
  [
    "Apples",
    502.61,
    "pos2",
    "11-26-19"
  ],
  [
    "Apples",
    502.61,
    "pos3",
    "11-26-19"
  ],
  [
    "Apples",
    502.16,
    "Apples",
    "11-26-19"
  ]
]

Comments

1

Here you go

let input = {
  "Apples": {
    "11-26-19": {
      "Apples_pos1": 501.82,
      "Apples_pos2": 502.61,
      "Apples_pos3": 502.61,
      "Apples": 502.16,
    }
  }
};

let output = [];

Object.keys(input).map(key1 => {
  Object.keys(input[key1]).map(key2 => {
    for(let key3 in input[key1][key2]) {
      output.push([key1, input[key1][key2][key3], key3.split('_')[1] || key3.split('_')[0], key2]);
    }
  });
})

console.log(output);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.