How to split a single-object array-item into an array of three objects?

92 Views Asked by At

Given is the response data's following data structure ...

const res = {
  data: [{
    name: 'c2',
    ipaddr: '192.168.1.5',
    port: 4435,
    sshuser: "abc",
    sshpass: "xyz",
    sshport: 22,
    license: 'license.txt',
  }],
};

I want to convert it to ...

const newState = [{
  name: 'c2',
  ipaddr: '192.168.1.5',
  port: 4435,
}, {
  sshuser: "abc",
  sshpass: "xyz",
  sshport: 22,
}, {
  license: 'license.txt',
}]

The below posted code does achieve the expected result ...

var obj1 = {
  name: res.data[0].name,
  ipaddr: res.data[0].ipaddr,
  port: res.data[0].port,
};
var obj2 = {
  sshuser: res.data[0].sshuser,
  sshpass: res.data[0].sshpass,
  sshport: res.data[0].sshport,
};
var obj3 = {
  license: res.data[0].license,
};
const newState = [obj1, obj2, obj3];

What are other ways of achieving the same result, maybe using a shorter syntax?

3

There are 3 best solutions below

0
Nick Parsons On BEST ANSWER

While your code is working fine and is a valid way to achieve this (although I'd suggest using const instead of var), I would suggest potentially performing a mapping (this can be useful if you have more than one object in your original array, perhaps then you can consider using .map() instead of .flatMap()):

const res = {data: [ {name: 'c2', ipaddr: '192.168.1.5', port: 4435, sshuser: "abc", sshpass: "xyz", sshport: 22, license: 'license.txt'}]};

const newState = res.data.flatMap(({name, ipaddr, port, sshuser, sshpass, sshport, license}) => [
  {name, ipaddr, port}, {sshuser, sshpass, sshport}, {license}
]);

console.log(newState);

Alternatively, you can destructure your objects from your array, and create the array of objects using shorthand property names:

const res = {data: [ {name: 'c2', ipaddr: '192.168.1.5', port: 4435, sshuser: "abc", sshpass: "xyz", sshport: 22, license: 'license.txt'}]};

const [{name, ipaddr, port, sshuser, sshpass, sshport, license}] = res.data;
const newState = [{name, ipaddr, port}, {sshuser, sshpass, sshport}, {license}];
console.log(newState);

0
Peter Seliger On

There is nothing wrong with how the result of the OP's example code gets achieved.

A solution which is built around object-destructuring and shorthand property-names might look similar to the next following code ...

const {
  name, ipaddr, port,
  sshuser, sshpass, sshport,
  license,
} = res.data[0];

const newState = [
  { name, ipaddr, port },
  { sshuser, sshpass, sshport },
  { license },
];
console.log('newState ...', newState);
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>
  const res = {
    data: [{
      name: 'c2',
      ipaddr: '192.168.1.5',
      port: 4435,
      sshuser: "abc",
      sshpass: "xyz",
      sshport: 22,
      license: 'license.txt',
    }],
  };
</script>

1
jsejcksn On

The approach that you choose when solving problems always depends on the intent of the goal.

^ If I can have one liner or only few lines, it will be good.

Fewer lines of code is not always better. Readable code is very useful.

If the intent is to take an object and create an array of objects in which each one is made up of a group of keys from the original object, then you can write a function to help you do that, and then you can use the function again later with any other type of object (even if it has different keys). Here's an example:

function pick(input, keys) {
  const output = {};
  for (const k of keys) output[k] = input[k];
  return output;
}

function toGroups(obj, groups) {
  return groups.map((keys) => pick(obj, keys));
}

const res = {
  data: [{
    name: "c2",
    ipaddr: "192.168.1.5",
    port: 4435,
    sshuser: "abc",
    sshpass: "xyz",
    sshport: 22,
    license: "license.txt",
  }],
};

const actual = toGroups(
  // The source object
  res.data[0],
  // The groups of keys for each object in the resulting array:
  [
    ["name", "ipaddr", "port"],
    ["sshuser", "sshpass", "sshport"],
    ["license"],
  ],
);

const expected = [{
  name: "c2",
  ipaddr: "192.168.1.5",
  port: 4435,
}, {
  sshuser: "abc",
  sshpass: "xyz",
  sshport: 22,
}, {
  license: "license.txt",
}];

console.log(JSON.stringify(actual) === JSON.stringify(expected)); // true