0

I have a json object like this:

{
    "sample1": {
      "4": 2245,
      "5": 2175,
      "6": 3495,
      "7": 1845,
      ...
      "11.5": 1674,
      "12.5": 1649
    },
    "sample2": {
      "4": 3295,
      "5": 3600,
      "8": 2625,
      "9": 2830,
      ...
      "11.5": 2879,
      "12.5": 3090
    }
}

and I want to format this to:

[
    {
        "index": "4",
        "sample1": "2245",
        "sample2": "3295"
    },
    {
        "index": "5",
        "sample1": "2175",
        "sample2": "3600"
    },
    {
        "index": "6",
        "sample1": "3495",
        "sample2": ""
    },
    ....
    {
        "index": "12.5",
        "sample1": "1649",
        "sample2": "3090"
    }
]

In python it's very easy to do this using pandas, but I don't want to add python script into javascript. Any simple way to do this using javascript?

4
  • What are the criteria to decide whether to add or not a key to the output object? For example, why the output object does not contain { index: "7", ... } (which is present only in sample 1) and { index: "11.5", ... } (which is present in both samples) but does contain { index: "6", ... } (which is present only in sample 1)? Commented Dec 4, 2020 at 11:29
  • @secan they have added ... in the output which indicates etc. and added the last item in the array. Commented Dec 4, 2020 at 12:28
  • @adiga, I know what "..." indicates but the code provided is not self-explanatory: looking at it you can assume the output should contain all element from both the samples but you can assume as well that the output object contains all element from sample1 and... what? All elements from sample2 that are also in sample1? Some elements from sample2 that are also in sample1? It does not matter, because they would all be unsubstantiated assumption unless some further explanation is provided or the code samples are modified so that they become self-explanatory. Commented Dec 4, 2020 at 14:05
  • @secan If it's not present, then it would be an empty string as shown with "sample2": "" for "index": "6". Yes, it would've been better if they had been explicit about it. Commented Dec 4, 2020 at 14:09

2 Answers 2

2

const data = {
  sample1: {
    4: 2245,
    5: 2175,
    6: 3495,
    7: 1845,
    11.5: 1674,
    12.5: 1649
  },
  sample2: {
    4: 3295,
    5: 3600,
    8: 2625,
    9: 2830,
    11.5: 2879,
    12.5: 3090
  },
  sample3: {
    4: 3295,
    5: 3600,
    6: 2625,
    9: 2830,
    11.5: 2879,
    12.5: 3090
  }
};

const keys = Object.keys(data);

const mergedInnerKeys = Array.from(
  new Set(
    keys
      .reduce((val, key) => [...val, ...Object.keys(data[key])], [])
      .sort((a, b) => a - b)
  )
);

const res = mergedInnerKeys.map((key) => ({
  index: key,
  ...keys.reduce(
    (v, k) => ({
      ...v,
      [k]: data[k][key] !== undefined ? data[k][key].toString() : ''
    }),
    {}
  )
}));
console.log(res);

Sign up to request clarification or add additional context in comments.

2 Comments

data[k][key] || '' will result in '' if data[k][key] is zero.
You can also get mergedInnerKeys like this: Array.from( new Set(Object.values(data).flatMap(Object.keys)) )
0

const obj = {
  "sample1": {
    "4": 2245,
    "5": 2175,
    "6": 3495,
    "7": 1845,
    "11.5": 1674,
    "12.5": 1649
  },
  "sample2": {
    "4": 3295,
    "5": 3600,
    "8": 2625,
    "9": 2830,
    "11.5": 2879,
    "12.5": 3090
  }
}

const result = Object.keys(obj.sample1) // All keys from sample1
  .concat(Object.keys(obj.sample2)) // Concat all keys from sample2
  .filter((v, i, s) => s.indexOf(v) == i) // Filter unique values
  .sort((a, b) => a - b) // Sort the keys, treating them as numbers
  .map(k => ({ // Produce each object of the resulting array, one per key
    index: k,
    sample1: k in obj.sample1 ? obj.sample1[k].toString() : '',
    sample2: k in obj.sample2 ? obj.sample2[k].toString() : ''
  }));

console.log(result);

2 Comments

Thanks a lot for the quick reply :) As in the real case it could have many samples, not only sample1 and sample2, so I think the baymax's solution is better. Thank you all the same!
@icebee Oh, ok. You used ... for the content of the samples, but didn't use it outside, so I figured the elements would always be 'sample1' and 'sample2'.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.