Javascript 如何转换数组以基于数据中的值保存数据?
我看到了一些看起来相似的问题,但在我的案例中没有一个是解决方案。我希望按照基于我的一个值(年龄)排列或分组的方式重新组合和重新创建数组。我希望在一个地方有相同“年龄”的所有数据。下面是我的示例阵列:Javascript 如何转换数组以基于数据中的值保存数据?,javascript,Javascript,我看到了一些看起来相似的问题,但在我的案例中没有一个是解决方案。我希望按照基于我的一个值(年龄)排列或分组的方式重新组合和重新创建数组。我希望在一个地方有相同“年龄”的所有数据。下面是我的示例阵列: [ { "age": 15, "person": { name: 'John', hobby: 'ski' }, }, { "age": 23, "person": { name: 'Suzi', h
[
{
"age": 15,
"person": {
name: 'John',
hobby: 'ski'
},
},
{
"age": 23,
"person": {
name: 'Suzi',
hobby: 'golf'
},
},
{
"age": 23,
"person": {
name: 'Joe',
hobby: 'books'
}
},{
"age": 25,
"person": {
name: 'Rosi',
hobby: 'books'
}
},{
"age": 15,
"person": {
name: 'Gary',
hobby: 'books'
}
},
{
"age": 23,
"person": {
name: 'Kane',
hobby: 'books'
}
}
]
我需要有一个数组,它以年龄作为键,以人作为值,所以每个键可以有多个值,这意味着值本身就是一个数组。
我读过很多书,问过很多问题,但它们并不完全相同。
我觉得我需要使用reduce来计算重复的年龄,然后在此基础上对其进行过滤,但是如何获得这些年龄的值呢
艾德:
对不起,我不清楚:
这就是我需要的:
{
23: [
{ name: 'Suzi', hoby: 'golf' },
{ name: 'Joe', hobby: 'books'}
],
15: [
{ name: 'Gary', hobby: 'books' }
] ,
.
.
.
}
实际上,您需要的是减少,而不是过滤。过滤数组意味着删除元素并将保留的元素放入新容器中。减少数组意味着将其转换为新容器中的单个值。映射数组意味着将每个值转换为一个新容器。因为您想更改数据的表示方式,所以这是一种简化,从一种形式到另一种更精简的形式 假设您的值数组存储在
let people=[…]
let peopleByAge = people.reduce(function (accumulator, value, index, array){
// The first time through accumulator is the passed extra Object after this function
// See the MDN for Array.prototype.reduce() for more information
if (accumulator[value.age] == undefined){
accumulator[value.age] = [];
}
accumulator[value.age].push(value);
return accumulator
}, {})
console.log(peopleByAge) // { 23: [{ age: 23, name: ..., hobby: ...}, ...], 13: [...], ...}
感谢@RobertMennell耐心地回答了我的问题,我投了赞成票。但我只是想写我的版本,MDN有一个很好的例子。它是一个较长的版本,假设人员是数组名称:
const groupedByvalue = 'age';
const groupedArray = people;
const groupBy = (peopleArray, value) => {
return peopleArray.reduce((acc, obj) => {
const key = obj[value];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(obj);
return acc;
}, {});
}
console.log(groupBy(groupedArray,groupedByvalue));
更新:
使用三元运算符进行更精细的抛光:
const groupedByvalue = 'age';
const groupedArray = people;
const groupBy = (peopleArray, value) => {
return peopleArray.reduce((acc, obj) => {
const key = obj[value];
(!acc[key]) ? (acc[key] = []) : (acc[key].push(obj))
return acc;
}, {});
}
console.log(groupBy(groupedArray,groupedByvalue));
您可能需要更仔细地了解JavaScript。我建议查看数组和对象的MDN,因为您似乎对JS中数据类型的工作方式有一点误解。除此之外,您正在询问的算法是一个简单的
Array.prototype.reduce()
(也称为Array#reduce()
)算法,该算法将花费时间并插入值。当然,这意味着您需要检查是否存在重复或类似的数据,但是如果您不担心reduce会超过enough,那么您需要更仔细地思考您的问题。以目前的形式,它会得到一大堆反对票,因为这个问题的形式不好,很难弄清楚你想要什么。这应该更接近于如何根据数据中的值转换数组以保存数据?
谢谢@RobertMennell。你完全正确。我更改了标题,将用Reduce解决它。投票赞成你的评论。谢谢。很高兴我能帮忙!你当然做了。干杯。你错了。它将第一个值转储到乙醚中。尝试acc[键]?(acc[key]=[obj]):(acc[key].push(obj))
当然我不想在这里使用三元,因为它更容易混淆,因为它既可以进行赋值,也可以进行方法调用。您应该改为将其作为可选赋值acc[key]=acc[key]| |[];acc[键]。推送(obj)代码>谢谢@RobertMennell。是的,在这种情况下我不应该。只是想把它缩短些,否则一切都好。干杯。另外,“无法读取未定义的属性‘push’”是我使用您的三元组时得到的。不知道为什么?哎呀,忘了一个否定词<代码>!acc[键]?(acc[key]=[obj]):(acc[key].push(obj))