4

I have a Map<String, Object> and I want to convert it to JSON.

Here is what I have:
Point 1: Declaring variables

var map = new Map(), //map
jsonObject= {}, // oject that needs to be converted to JSON
value1 = { topic: "someText1", status: "0", action: "1", comment: "someComment1" }, // values of Map
value2 = { topic: "someText2", status: "0", action: "0", comment: "someComment2" },
value3 = { topic: "someText3", status: "1", action: "1", comment: "someComment3" };

Point 2: populating Map
// key of map is concatenation of various attributes from web page, separated by |

map.set('release|attachment|license1|topic1', value1);
map.set('release|attachment|license1|topic2', value1);
map.set('release1|attachment1|license1|topic1', value1);
map.set('release1|attachment1|license2|topic2', value2);
map.set('release1|attachment1|license3|topic3', value3);
map.set('release2|attachment2|license2|topic2', value2);
map.set('release2|attachment2|license2|topic3', value2);

Point 3: iterating map and populating jsonObject

for (const [key, values] of map) {
    setPath(jsonObject, key.split('|'), values);
}
function setPath(obj, [...keys], item) {
    keys.pop(); // removing topic
    const last = keys.pop();
    keys.reduce((r, a) => r[a] = r[a] || {}, obj)[last] =  [item];
}

Point 4: current output [console.log(JSON.stringify(jsonObject));]

{
  "release": {
    "attachment": {
      "license1": [
        {
          "topic": "someText2",
          "status": "0",
          "action": "0",
          "comment": "someComment2"
        }
      ]
    }
  },
  "release1": {
    "attachment1": {
      "license1": [
        {
          "topic": "someText1",
          "status": "0",
          "action": "1",
          "comment": "someComment1"
        }
      ],
      "license2": [
        {
          "topic": "someText2",
          "status": "0",
          "action": "0",
          "comment": "someComment2"
        }
      ],
      "license3": [
        {
          "topic": "someText3",
          "status": "1",
          "action": "1",
          "comment": "someComment3"
        }
      ]
    }
  },
  "release2": {
    "attachment2": {
      "license2": [
        {
          "topic": "someText3",
          "status": "1",
          "action": "1",
          "comment": "someComment3"
        }
      ]
    }
  }
}

Point 5: expected output (jsonObject)

{
  "release": {
    "attachment": {
      "license1": [
        {
          "topic": "someText1", // ^^ This object is missing in current output.
          "status": "0",
          "action": "1",
          "comment": "someComment1"
        },
        {
          "topic": "someText2",
          "status": "0",
          "action": "0",
          "comment": "someComment2"
        }
      ]
    }
  },
  "release1": {
    "attachment1": {
      "license1": [
        {
          "topic": "someText1",
          "status": "0",
          "action": "1",
          "comment": "someComment1"
        }
      ],
      "license2": [
        {
          "topic": "someText2",
          "status": "0",
          "action": "0",
          "comment": "someComment2"
        }
      ],
      "license3": [
        {
          "topic": "someText3",
          "status": "1",
          "action": "1",
          "comment": "someComment3"
        }
      ]
    }
  },
  "release2": {
    "attachment2": {
      "license2": [
        {
          "topic": "someText2", // ^^ This object is missing in current output.
          "status": "0",
          "action": "0",
          "comment": "someComment2"
        },
        {
          "topic": "someText3",
          "status": "1",
          "action": "1",
          "comment": "someComment3"
        }
      ]
    }
  }
}

^^ I want to have array of objects in jsonObject.

Can someone help me with tweak needs to be done in setPath function in Point 3 to obtain expected result?

PS: I know that I have asked similar question here.

1
  • 1
    Are you sure you want to do map.set('release|attachment|license1|topic1', value1); twice? Commented Jul 29, 2019 at 11:45

1 Answer 1

2

You are overwriting the license arrays instead of just appending the new items.

Change this line

keys.reduce((r, a) => r[a] = r[a] || {}, obj)[last] =  [item];

to this

const target = keys.reduce((r, a) => r[a] = r[a] || {}, obj);
(target[last] = target[last] || []).push(item);
Sign up to request clarification or add additional context in comments.

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.