1
{
    Type: "Fire",
    Name: "Shark",
    StartRange0: "10",
    EndRange0: "20",
    StartRange1: "30",
    EndRange1: "40",
    StartRange2: "60",
    EndRange2: "70"
}

In the above object, StartRange and EndRange can be more items in different objects. i.e those values are obtained from a loop( StartRange + index), so there maybe StartRange1,2,3... lly, EndRange1,2,3...

The above object structure must be changed to,

{
   "Fire":{
      "Name":"Shark",
      "List":[
         [
            "10",
            "20"
         ],
         [
            "30",
            "40"
         ],
         [
            "60",
            "70"
         ]
      ]
   }
}

The List array inside the object is combination of [StartRange0,EndRange0],[StartRange1,EndRange2]... So on...

I tried,

let newObj = {}
newObj[oldObj.Type] = {
    Name: oldObj.Name, //oldObj is the first object defined above.
    List: [[oldObj.StartRange0,oldObj.EndRange0],[oldObj.tartRange1,oldObj.EndRange1],[oldObj.StartRange2,oldObj.EndRange2]]
}

But here, it is limited to StartRange2 and EndRange2 but I need it for StartRangeN and EndRangeN.

Sai Krishnadas
  • 2,863
  • 9
  • 36
  • 69
  • 3
    Where do you get the object from? Can you fix the code that is creating it? – Bergi Jun 17 '22 at 04:10
  • I'm getting it from a form.current that loop over a form.item and the name of form.item is StartRange + index (which would give StartRange0,StartRange1 and so on) – Sai Krishnadas Jun 17 '22 at 04:12
  • chunk the `Object.values` of the rest in `{Type,Name...rest}` ? https://stackoverflow.com/questions/8495687/split-array-into-chunks – cmgchess Jun 17 '22 at 04:19
  • 1
    @SaiKrishnadas Can you show that code? And can you change the form? `StartRange[0]` might be slightly nicer to process (but if you need unique names I guess there's nothing you can do) – Bergi Jun 17 '22 at 04:21
  • 2
    @cmgchess No, that will ignore the keys, which are important – Bergi Jun 17 '22 at 04:22

3 Answers3

3

This is how I would have done map it

const input = {
  Type: "Fire",
  Name: "Shark",
  StartRange0: "10",
  EndRange0: "20",
  StartRange1: "30",
  EndRange1: "40",
  StartRange2: "60",
  EndRange2: "70"
}

const toList = (l) => Array.from({
  length: Object.keys(l).length / 2
}, (_, N) => [l[`StartRange${N}`], l[`EndRange${N}`]])

const toOutput = ({ Type, Name, ...rest }) => {
  const List = toList(rest)
  return ({
    [Type]: {
      Name,
      List
    }
  })
}

const output = toOutput(input)
console.log(output)
Teneff
  • 30,564
  • 13
  • 72
  • 103
  • This works perfectly as expected. But one thing i left out, the all values in the list of list should be string i.e ["10","20"]. Upon adding new ranges which is actually a number, how will I covert them to string in this code ? – Sai Krishnadas Jun 17 '22 at 04:44
  • 1
    Adding this worked, `[String(l[`StartRange${N}`]), String(l[`EndRange${N}`])]`. Thanks – Sai Krishnadas Jun 17 '22 at 04:45
  • 1
    or `[l[\`StartRange${N}\`], l[\`EndRange${N}\`]].map(String)` – Teneff Jun 17 '22 at 04:46
  • Yeah, That too works, but in a case like 100 ranges, that would loop through each and convert to string right? Kind of makes the process slow – Sai Krishnadas Jun 17 '22 at 04:56
2

You can play around with this example

const object = {
  Type: "Fire",
  Name: "Shark",
  StartRange0: "10",
  EndRange0: "20",
  StartRange1: "30",
  EndRange1: "40",
  StartRange2: "60",
  EndRange2: "70"
};

let index = 0;
let isFinished = false;
const results = [];

while (!isFinished) {
  const startKey = `StartRange${index}`;
  const endKey = `EndRange${index}`;

  isFinished = !object.hasOwnProperty(startKey) || !object.hasOwnProperty(endKey);

  !isFinished && results.push([object[startKey], object[endKey]]);

  index++;
}

console.log(results);
Thanh Dao
  • 1,218
  • 2
  • 16
  • 43
0

This may work but it would be better if you could change that structure and use another one.

const test = {
  Type: "Fire",
  Name: "Shark",
  StartRange0: "10",
  EndRange0: "20",
  StartRange1: "30",
  EndRange1: "40",
  StartRange2: "60",
  EndRange2: "70",
};

const format = (obj) => {
  const { Type, Name, ...rest } = obj;
  const list = [];
  const keys = Object.keys(rest);
  for (let index = 0; index < keys.length; index++) {
    const start = rest[`StartRange${index}`];
    const end = rest[`EndRange${index}`];
    if (start && end) {
      list.push([start, end]);
    } else {
      break; // assuming you don't have any other elements
    }
  }
  return {
    [Type]: {
      Name,
      List: list,
    },
  };
};

console.log(JSON.stringify(format(test)));
Gustavo A Olmedo
  • 565
  • 4
  • 13