javascriptobservable-plot

Flatten and transform data in Javascript


Given this object (items per array is the same) :

{
    force_x: [6, 7, 7],
    force_y: [2, 3, 4],
    timestamp: [0.08, 0.016, 0.024]
}

How could I use Javascript to create this for all keys except timestamp :

{
    {mode: "force_x", value: 6, timestamp: 0.08},
    {mode: "force_x", value: 7, timestamp: 0.16},
    {mode: "force_x", value: 7, timestamp: 0.24},
    {mode: "force_y", value: 2, timestamp: 0.08},
    {mode: "force_y", value: 3, timestamp: 0.16},
    {mode: "force_y", value: 4, timestamp: 0.24},
}

Note that the timestamp array can be removed from the object, if it's easier to handle. The algorithm should not specify the force_x and force_y keys and do it automatically for each keys.


Solution

  • Here's a nice little one-liner:

    const data = {
        force_x: [6, 7, 7],
        force_y: [2, 3, 4],
        timestamp: [0.08, 0.016, 0.024]
    };
    
    const {  timestamp, ...props } = data;
    
    const result = Object.keys(props).flatMap((mode) => props[mode].map((value, i) => ({ mode, value, timestamp: timestamp[i] })));
    
    console.log(result);

    First, we exclude timestamp from the data. Then for each key, we need to map it to its "expanded form". To do this, we map each value of the key to an object. While mapping, we get the index of the element and use that to get the corresponding timestamp for the object. However, this will give us an array of the form [[{ ... }, { ... }], ...], so we have to flatten it. Fortunately, there is a shortcut for us and that is flatMap, which is equivalent to using map and then flat.