Khorkhe
Khorkhe

Reputation: 1126

ES6 spread syntax on array of objects, and getting object properties

I have an array of objects as follows:

const data = [
  {
    'name': 'A',
    'v0': true,
    'values': [
      { 'v': true, 'k': 1 },
      { 'v': false, 'k': 2 },
      { 'v': true, 'k': 3 },
      { 'v': false, 'k': 4 }
    ]'
  },
  ...
]

the function below extracts the params name, v0 and values from the data objects and is used to render a row of a table by creating an array of cells with properties.

v0 is a boolean, and depending on its value, the render function may apply some styling to the cell.

This works fine when the number of values is predetermined, as they can be listed: v0, v1 ...

However, I have an array of values instead, and would like to spread it, while applying a unique key, as shown in v0 below:

const renderBodyRow = ({ name, v0, values }) => ({
  cells: [
    name,
    v0 ? { key: '0', content: v0, color: 'green' } : { key: '0', content: v0, color: 'red' },
    ...values //  need to apply the same, but on the values array

  ]
})

One way is to have values as a array of booleans: values: [true, false, true, false]

This would require the creation of a unique key inside the renderBodyRow function. Is this possible?

Or define the values array as an array of objects with value and key. In which case, how would spread syntax be able to access the properties of those objects?

Any idea on how to achieve either (or both) of these with spread syntax?

Thanks

Upvotes: 0

Views: 4123

Answers (2)

Bergi
Bergi

Reputation: 665020

You seem to be looking for

function renderBodyCell({ k, v }) {
  return {
    key: k,
    content: v,
    color: v ? 'green' : 'red'
  };
}
function renderBodyRow({ name, v0, values }) {
  return {
    cells: [
      name,
      renderBodyCell({ k: '0', v: v0 }),
      ... values.map(renderBodyCell)
    ]
  };
}

Upvotes: 3

castletheperson
castletheperson

Reputation: 33496

You will need to use Array.prototype.map in order to convert each value into an object with the desired style. You can make values a boolean array, and then use the index of each value as the unique key.

const data = [{
  name: 'A',
  values: [true, true, false, true, false]
}];

const renderBodyRow = ({ name, values }) => ({
  cells: [
    name,
    ...values.map((val, index) => ({
      key: String(index),
      content: val,
      color: val ? 'green' : 'red'
    }))
  ]
});

console.log(data.map(renderBodyRow));
.as-console-wrapper { max-height: 100% !important; }

Upvotes: 4

Related Questions