0

I have a Json data that I want to have in a different format.

My original json data is:

{
  "info": {
    "file1": {
      "book1": {
        "lines": {
          "102:0": [
            "102:0"
          ],
          "105:4": [
            "106:4"
          ],
          "106:4": [
            "107:1",
            "108:1"
          ]
        }
      }
    }
  }
}

And I want to map it as following:

{
  "name": "main",
  "children": [
    {
      "name": "file1",
      "children": [
        {
          "name": "book1",
          "group": "1",
          "lines": [
            "102",
            "102"
          ],
          [
            "105",
            "106"
          ],
          [
            "106",
            "107",
            "108"
          ]
        }
      ],
      "group": 1,

    }
  ],
  "group": 0
}

But the number of books and number of files will be more. Here in the lines the 1st part (before the :) inside the "" is taken ("106:4" becomes "106"). The number from the key goes 1st and then the number(s) from the value goes and make a list (["106", "107", "108"]). The group information is new and it depends on parent-child information. 1st parent is group 0 and so on. The first name ("main") is also user defined.

I tried the following code so far:

function build(data) {
    return Object.entries(data).reduce((r, [key, value], idx) => {
      //const obj = {}
      const obj = {
        name: 'main',
        children: [],
        group: 0,
        lines: []
      }

      if (key !== 'reduced control flow') {
        obj.name = key;
        obj.children = build(value)
          if(!(key.includes(":")))
          obj.group = idx + 1;
      } else {
        if (!obj.lines) obj.lines = [];
        Object.entries(value).forEach(([k, v]) => {
          obj.lines.push([k, ...v].map(e => e.split(':').shift()))
        })
      }

      r.push(obj)
      return r;
    }, [])
  }

  const result = build(data);
  console.log(result);

The group information is not generating correctly. I am trying to figure out that how to get the correct group information. I would really appreciate if you can help me to figure it out.

3
  • 1
    How do you get group value? Shouldn't it be "name": "info" instead of "name": "main" Commented Dec 20, 2019 at 8:02
  • Those are based on other conditions and not related with "lines" information. That's why I didn't mention it. Commented Dec 20, 2019 at 8:08
  • 1
    your output json is not valid. Commented Dec 20, 2019 at 8:21

2 Answers 2

3

You could use reduce method and create recursive function to build the nested structure.

const data = {"info":{"file1":{"book1":{"lines":{"102:0":["102:0"],"105:4":["106:4"],"106:4":["107:1","108:1"]}}}}}

function build(data) {
  return Object.entries(data).reduce((r, [key, value]) => {
    const obj = {}

    if (key !== 'lines') {
      obj.name = key;
      obj.children = build(value)
    } else {
      if (!obj.lines) obj.lines = [];
      Object.entries(value).forEach(([k, v]) => {
        obj.lines.push([k, ...v].map(e => e.split(':').shift()))
      })
    }

    r.push(obj)
    return r;
  }, [])
}

const result = build(data);
console.log(result);

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

Comments

0

I couldn't understand the logic behind group property, so you might need to add more info for that, but for the rest, you can try these 2 functions that recursively transform the object into what you are trying to get.

var a = {"info":{"file1":{"book1":{"lines":{"102:0":["102:0"],"105:4":["106:4"],"106:4":["107:1","108:1"]}}}}};

var transform = function (o) {
    return Object.keys(o)
            .map((k) => { 
                  return {"name": k, "children": (k === "lines" ? parseLines(o[k]) : transform(o[k])) } 
              }
            )
}

var parseLines = function (lines) {
    return Object.keys(lines)
            .map(v => [v.split(':')[0], ...(lines[v].map(l => l.split(":")[0]))])
}

console.log(JSON.stringify(transform(a)[0], null, 2));

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.