🏠 back to Observable

how to change the key of object to an array or another key?

Dear all, the codes like follows:

https://observablehq.com/d/688b78aab7723664

what should I do if I want to change the key ‘step’ of all these 9 objects to an array like [0,1,2], or to another key, like ‘step_2’, by writing codes, rather than change it directly in the data files?

You could do this by passing a row conversion function to d3.csvParse:

data = d3.csvParse(await mat.text(), row => {
  row['step'] = [1, 2, 3];
  return row;
})  
data = d3.csvParse(await mat.text(), row => {
  return {
    step_2: row.step,
    temp: row.temp,
    SR: row.SR,
    mis: row.mis,
    Tmax: row.Tmax
  }
})

Or, you could use map to do this:

updatedData = data.map(d => {
  // shallow copy so that we don't modify the objects in `data`
  const obj = {...d};
  obj['step'] = [0, 1, 2];
  return obj;
})
data.map(d => {
  // shallow copy so that we don't modify the objects in `data`
  const obj = {...d};
  // create a new key value pair
  obj['step_2'] = obj['step'];
  // delete the old key value pair
  delete obj['step'];
  return obj;
})
2 Likes

You can use destructuring to transform your objects:

data = (await FileAttachment("Book1.csv").csv())
  .map(({step, ...o}, i) => ({
    ...o,
    [`step_${i}`]: [1,2,3]
  }))

In detail:

(await FileAttachment("Book1.csv").csv())

There’s no need to use d3.csvParse, it’s built into FileAttachment already. Because the return value is a promise, we use await to obtain and pass on the eventual value.

.map(({step, ...o}, i) => ({

Here we destructure each entry, filtering out the step property. All remaining properties end up in o. Note the ({, indicating that we straight away return an object.

    ...o,

Destructure o into the new object, i.e., copy over all keys and values.

    [`step_${i}`]: [1,2,3]

Set a dynamic property step_${i}. Assign the property the array [1, 2, 3].

4 Likes

Thanks @mootari! I often wish I had a helpful person to talk through code in exactly this way!