1

I'm brand new to ES6 and I have an array of objects that looks like:

locations: [
  {
    "is_moving": true,
    "uuid": "82fa9dda-e57b-4b3f-99a0-a1db98ae4a19",
    "timestamp": "2017-08-05T04:48:25.526Z",
    "odometer": 0,
    "sample": true,
    "coords": {
      "latitude": 32.7323862,
      "longitude": -117.1939315,
      "accuracy": 1000,
      "speed": -1,
      "heading": -1,
      "altitude": -1
    },
    "activity": {
      "type": "in_vehicle",
      "confidence": 54
    },
    "battery": {
      "is_charging": false,
      "level": 0.5
    },
    "extras": {}
  },
  {
    "event": "motionchange",
    "is_moving": true,
    "uuid": "57a0146a-28b9-4baf-86de-e037843c2d32",
    "timestamp": "2017-08-05T04:48:25.526Z",
    "odometer": 0,
    "coords": {
      "latitude": 32.7323862,
      "longitude": -117.1939315,
      "accuracy": 1000,
      "speed": -1,
      "heading": -1,
      "altitude": -1
    },
    "activity": {
      "type": "in_vehicle",
      "confidence": 54
    },
    "battery": {
      "is_charging": false,
      "level": 0.5
    },
    "extras": {}
  }
]

What I want to end up with is:

locations: [
  {
    "timestamp": "2017-08-05T04:48:25.526Z",
    "odometer": 0,
    "latitude": 32.7323862,
    "longitude": -117.1939315,
    "accuracy": 1000,
    "speed": -1,
    "heading": -1,
    "altitude": -1
  },
  {
    "timestamp": "2017-08-05T04:48:25.526Z",
    "odometer": 0,
    "latitude": 32.7323862,
    "longitude": -117.1939315,
    "accuracy": 1000,
    "speed": -1,
    "heading": -1,
    "altitude": -1
  }
]

So I know I can filter out the key/value pairs that I don't want by doing (thanks to https://stackoverflow.com/a/39333664/994275):

locations.map(({ timestamp, odometer, coords }) => ({ timestamp, odometer, coords }))

and I know I can flatten the objects by doing (thanks to https://stackoverflow.com/a/33037683/994275):

Object.assign(
  {}, 
  ...function _flatten(location) { 
    return [].concat(...Object.keys(location)
      .map(k => 
        typeof location[k] === 'object' ?
          _flatten(location[k]) : 
          ({[k]: location[k]})
      )
    );
  }(location)
)

But I'm trying to combine the two and failing miserably. I've added the flatten within the map, but that's just returning an array of undefined.

I'm sure there's an easy fix, but it's eluding me at this point. Any help would be greatly appreciated!

Here's what worked (thanks to the user who seems to have removed their comments):

let newLocations = locations.map(({ is_moving, uuid, timestamp, odometer, coords }) => ({ is_moving, uuid, timestamp, odometer, coords }));
let test = newLocations.map((location) => {
  return Object.assign(
    {}, 
    ...function _flatten(location) { 
      return [].concat(...Object.keys(location)
        .map(k => 
          typeof location[k] === 'object' ?
            _flatten(location[k]) : 
            ({[k]: location[k]})
        )
      );
    }(location)
  )
});

Is there a way to condense the filtering and flattening?

JulieMarie
  • 400
  • 1
  • 6
  • 21

1 Answers1

0

The function body of an arrow function has two syntaxes: one with a "block body", and one with a "concise body". When you're using a "block body", you have to surround the contained statement(s) in a block using curly-brackets { }, and an explicit return statement is required if you don't want to return undefined.

You can combine your two operations into a single map and use the "concise body" syntax:

let newLocations = locations.map(({ is_moving, uuid, timestamp, odometer, coords }) =>
  Object.assign(
    {}, 
    ...function _flatten(location) { 
      return [].concat(...Object.keys(location)
        .map(k => 
          typeof location[k] === 'object' ?
            _flatten(location[k]) : 
            ({[k]: location[k]})
        )
      );
    }({ is_moving, uuid, timestamp, odometer, coords })
  )
);
4castle
  • 32,613
  • 11
  • 69
  • 106