如何获取一个包含数组对象内所有属性值的数组?

4

我想要获取每个对象的值的数组。

我有这样一个东西:

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}
    }
  ];

我需要这个:

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

我尝试了这个:

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

但它抛出了这个错误:

未捕获的 TypeErrorarray.map 不是一个函数


你没有一个数组的数组,所以你不能在这里使用 array.map - Luca Kiebel
那些不是数组,而是对象。你期望的排序不清楚。难道[[[807, 625], [15, 20], [5, 20]], [[11, 6], [16, 21], [7, 22]]]不是你需要的吗? - Sebastian Simon
只是为了严谨起见,在这里你不能再使用map _第二次_:第一个numDataPoints.map是可以的。 - msanford
Luca是正确的。看起来你有一个对象数组。你可以很好地map外部数组,但在内部对象中,你可能需要遍历对象键而不是使用数组方法。遍历对象键应该在SO上有相当充分的文档记录,因为这是一个常见的问题。 - Tyler Roper
$array = (array) $yourObject; - Andrew
显示剩余3条评论
8个回答

7
您可以使用Object.values和展开语法...map方法一起使用。

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)


5
你可以使用 Array.map 将每个对象转换为一个由两个元素的数组组成的数组,然后再使用 reduce 方法将结果展平:

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);


从波兰转到都柏林了吗? - Ashh
@Ashh 是的,暂时在这里工作,但仍然热爱波兰 :) - mickl

4
使用reduce进行操作 - 下面的代码适用于其他数据,因为我们没有在此处硬编码任何键名。

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>


1
你的numDataPoints数组中没有数组,而是普通对象,所以不能使用map。你需要使用Object.values。或者,为了保证键x0x1x2的顺序相同,可以使用{x0, x1, x2}进行解构,然后使用[x0, x1, x2]numDataPoints的结构表明,您实际上想要一个由两个数组组成的数组,每个数组有三个[x, y]点,而不仅仅是六个[x, y]点。如果您仍然想展开这些子数组,请使用concatflatMap(目前是第三阶段候选人,可能成为在2019年6月最终确定的ECMAScript版本的一部分)。
以下是所有六种可能性:

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])));


第一个嵌套在额外的数组中。 - charlietfl
@charlietfl 没错,第四个也是。我现在已经澄清了。 - Sebastian Simon

0

这是因为你得到的是一个对象,而不是一个数组。虽然你可以尝试(ES6):

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

0
问题在于array是一个对象,因此您必须在使用另一个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)

0
你可以使用 Object.keys 来遍历对象中的键,如下所示:

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);

你可能想要将结果展平,我不确定。


0
以下是几种不同的方法可以获得两个不同的结果(原始嵌套结构或平面结构),同时注意排序,这可能是您的一个用例 - 字典键按它们声明的方式排序(而不是按字母数字顺序):

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; }, [])
);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接