4

I want to get an array of the values of each object I have.

I have this:

const numDataPoints = [
    {
      x0: {x: 807, y: 625},
      x1: {x: 15, y: 20},
      x2: {x: 5, y: 20}
    },
    {
      x0: {x: 11, y: 6},
      x1: {x: 16, y: 21},
      x2: {x: 7, y: 22}
    }
  ];

I want this:

[
  [807, 625],
  [15, 20],
  [5, 20],
  [11, 6],
  [16, 21],
  [7, 22]
]

I tried this:

numDataPoints.map((array) => array.map(axis => [axis.x, axis.y]));

but it throws this error:

Uncaught TypeError: array.map is not a function

8
  • You don't have an array of arrays, you can't use array.map here Commented Jun 4, 2018 at 19:17
  • so, then what can i do? or how can i edit my question? Commented Jun 4, 2018 at 19:18
  • Those aren’t arrays. Those are objects. It’s not clear what ordering you expect. Isn’t [[[807, 625], [15, 20], [5, 20]], [[11, 6], [16, 21], [7, 22]]] what you’d need here? Commented Jun 4, 2018 at 19:18
  • Just to be pedantic, you can't use map a second time here: the first numDataPoints.map is fine. Commented Jun 4, 2018 at 19:18
  • Luca is correct. It looks like you have an array of objects of objects. You can map the outside array just fine, it's the inside object(s) where you'd likely need to loop through object keys rather than using array methods. Looping through object keys should be reasonably well documented here on SO as it's a commonly asked question. Commented Jun 4, 2018 at 19:19

8 Answers 8

7

You can use map method with Object.values and spread syntax ....

const data =  [{ x0: {x: 807, y: 625}, x1: {x: 15, y: 20}, x2: {x: 5, y: 20} }, { x0: {x: 11, y: 6}, x1: {x: 16, y: 21}, x2: {x:7, y: 22} }];

const result = [].concat(...data.map(Object.values)).map(Object.values)
console.log(result)

Sign up to request clarification or add additional context in comments.

Comments

5

You can use Array.map to transform each object into an array of two-element arrays and then reduce to flatten the result:

const numDataPoints =  [{ x0: {x: 807, y: 625}, x1: {x: 15, y: 20},
            x2: {x: 5, y: 20} }, { x0: {x: 11, y: 6}, x1: {x: 16, y: 21}, x2: {x:7, y: 22} }];

let result = numDataPoints.map(
    item => Object.values(item).map(({x, y})=> [x, y]))
              .reduce((arr, current) => [...arr, ...current], []);

  console.log(result);

2 Comments

Switched from poland to dublin?
@Ashh yes, temporarily, still love Poland but have assignment here :)
4

Use reduce for that - below will work for other data too as we don't hardcode any key's names here.

const res = numDataPoints.reduce((a, b) => a.concat(Object.keys(b).map(e => Object.values(b[e]))), []);
console.log(res);
<script>
const numDataPoints = [
    {
        x0: {
            x: 807,
            y: 625
        },
        x1: {
            x: 15,
            y: 20
        },
        x2: {
            x: 5,
            y: 20
        }
    }, {
        x0: {
            x: 11,
            y: 6
        },
        x1: {
            x: 16,
            y: 21
        },
        x2: {
            x: 7,
            y: 22
        }
    }
];
</script>

Comments

1

You don’t have arrays in your numDataPoints array, but regular objects, so you can’t use map.

What you need is Object.values. Alternatively, to guarantee the same order of the keys x0, x1 and x2, destructure with {x0, x1, x2} and then use [x0, x1, x2].

The structure of numDataPoints suggests, that you actually want an array of two arrays, each with three [x, y] points, rather than just six [x, y] points. If you still want to flatten these sub-arrays, use concat or flatMap (currently a Stage 3 candidate, likely to become part of the ECMAScript edition finalized in June 2019).

Here are all six possibilities:

const numDataPoints = [
    {
      x0: {x: 807, y: 625},
      x1: {x: 15, y: 20},
      x2: {x: 5, y: 20}
    },
    {
      x0: {x: 11, y: 6},
      x1: {x: 16, y: 21},
      x2: {x: 7, y: 22}
    }
  ];

// Object.values, same structure
console.log(numDataPoints.map((obj) => Object.values(obj).map(({x, y}) => [x, y])));

// Object.values, flattened with concat
console.log([].concat(...numDataPoints.map((obj) => Object.values(obj).map(({x, y}) => [x, y]))));

// Object.values, flattened with flatMap
console.log(numDataPoints.flatMap((obj) => Object.values(obj).map(({x, y}) => [x, y])));

// Destructuring, same structure
console.log(numDataPoints.map(({x0, x1, x2}) => [x0, x1, x2].map(({x, y}) => [x, y])));

// Destructuring, flattened with concat
console.log([].concat(...numDataPoints.map(({x0, x1, x2}) => [x0, x1, x2].map(({x, y}) => [x, y]))));

// Destructuring, flattened with flatMap
console.log(numDataPoints.flatMap(({x0, x1, x2}) => [x0, x1, x2].map(({x, y}) => [x, y])));

2 Comments

first one nests in extra array
@charlietfl Exactly, the fourth one too. I’ve clarified that now.
0

You can use Object.keys to iterate over the keys within the object, like so:

let data = [{
  x0: {
    x: 807,
    y: 625
  },
  x1: {
    x: 15,
    y: 20
  },
  x2: {
    x: 5,
    y: 20
  }
}, {
  x0: {
    x: 11,
    y: 6
  },
  x1: {
    x: 16,
    y: 21
  },
  x2: {
    x: 7,
    y: 22
  }
}];

let result = data.map(obj => Object.keys(obj).map((key) => [obj[key].x, obj[key].y]));

console.log(result);

You may want to flatten the result, I'm not sure.

Comments

0

This is because what you get is an object, not an array. Although you could try (Es6) :

numDataPoints
.map(_ => {
  return Object.values(_)
  .map(({x, y}) => [x, y]);
}).reduce((acc, elem) => [...acc, ...elem], []);

Comments

0

The problem is that array is an object, so you have to map the keys before using another forEach.

const numDataPoints =  [{ x0: {x: 807, y: 625}, x1: {x: 15, y: 20},x2: {x: 5, y: 20} }, { x0: {x: 11, y: 6}, x1: {x: 16, y: 21}, x2: {x:7, y: 22} }];
var foo = []
numDataPoints.forEach((points) => 
    Object.keys(points).forEach(point => 
        foo.push( [points[point].x, points[point].y] )
    )
);
console.log(foo)

Comments

0

Here are a few different ways to get two different results (original nesting structure or flat structure) - also notice the sorting which could be a use-case for you - dictionary keys are sorted in the way they are declared (not alphanumerically):

const numDataPoints =  [{ x0: {x: 807, y: 625}, x1: {x: 15, y: 20},
x2: {x: 5, y: 20} }, { x0: {x: 11, y: 6}, x1: {x: 16, y: 21}, x2: {x:7, y: 22} }];

// In case you need them sorted and in the original nesting:
console.log(
  numDataPoints
    .map(d => Object.keys(d).sort().map(k => [d[k].x, d[k].y]))
);

// In case you need them sorted and flattened:
console.log(
  numDataPoints
    .map(d => Object.keys(d).sort().map(k => [d[k].x, d[k].y]))
    .reduce((a,v) => { v.forEach(value => a.push(value)); return a; }, [])
);

// In case you don't need them sorted and in the original nesting:
console.log(
  numDataPoints
    .map(d => Object.keys(d).map(k => [d[k].x, d[k].y]))
);

// In case you don't need them sorted and flattened:
console.log(
  numDataPoints
    .map(d => Object.keys(d).map(k => [d[k].x, d[k].y]))
    .reduce((a,v) => { v.forEach(value => a.push(value)); return a; }, [])
);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.