gpt4 book ai didi

javascript - 通过对记录进行分组来获取数组的映射

转载 作者:行者123 更新时间:2023-11-29 16:32:30 26 4
gpt4 key购买 nike

我正在尝试使用 D3 转换一些数据,以获得按月分组的每天平均数量(数组映射)。数据如下所示:

data = [
{day: "mon", amount: "4", month: "jan"},
{day: "tue", amount: "2", month: "jan"},
{day: "wed", amount: "3", month: "jan"},
{day: "wed", amount: "1", month: "jan"}
]

我试图获得的输出应如下所示:

{"jan": [
{day:"mon", avg_amount:"4"},
{day:"tue", avg_amount:"2"},
{day:"wed", avg_amount:"2"}
]}

我已经尝试过使用 D3 的分组和汇总功能,但我只能获得 map 的 map ,这并不完全是我想要的。

d3.rollup(data, 
v => d3.mean(v, d => d.amount),
d => d.month, d => d.day);

我是 D3 的新手,所以我不确定如何实现这样的结果。有没有简单的方法可以用 D3 做到这一点?

最佳答案

尽管您的问题标题为“ map ”,并且您在问题正文中多次提到“ map ”,但您还是将所需的结果写为对象,可能是因为很难写 Map在问题的正文中。更好的方法可能是:

Map(1) {
"jan" => [
{day:"mon", avg_amount:"4"},
{day:"tue", avg_amount:"2"},
{day:"wed", avg_amount:"2"}
]
}

所以我假设您实际上是在请求一个 Map(特别是因为您使用的是 d3.rollup,它返回一个 Map)。但是,为了安全起见,我将提供两种解决方案,其中一种使用 d3.rollup 创建真正的 Map另一个使用 d3.nest 创建一个对象,以防万一。

使用 d3.rollup 进行映射

如果你想要的确实是一个Map,只需更改d3.rollup中的reduce函数即可:

d3.rollup(iterable, reduce, ...keys)
//this part ----------^

或者,就您而言:

d3.rollup(data, 
v => d3.mean(v, d => d.amount),//this is the reduce
d => d.month, d => d.day);//2 keys here

这是我将使用的减少:

v => v.reduce((a, b) => {
const found = a.find(d => d.day === b.day);
if (!found) {
a.push({
day: b.day,
avg_amount: +b.amount
})
} else {
found.avg_amount = (found.avg_amount + (+b.amount)) / 2
};
return a;
}, [])

顺便说一下,该汇总中有 2 个 key ,请删除最后一个。最后,请记住您拥有的是字符串,而不是数字。相应地强制他们。

这是一个演示。不要使用代码片段控制台(它只会显示 {}),请检查浏览器的控制台:

data = [{
day: "mon",
amount: "4",
month: "jan"
},
{
day: "tue",
amount: "2",
month: "jan"
},
{
day: "wed",
amount: "3",
month: "jan"
},
{
day: "wed",
amount: "1",
month: "jan"
}
];

const nested = d3.rollup(data,
v => v.reduce((a, b) => {
const found = a.find(d => d.day === b.day);
if (!found) {
a.push({
day: b.day,
avg_amount: +b.amount
})
} else {
found.avg_amount = (found.avg_amount + (+b.amount)) / 2
};
return a;
}, []),
d => d.month);

console.log(nested)
<script src="https://d3js.org/d3-array.v2.min.js"></script>

带有 d3.nest 的对象

另一方面,如果您想要的是使用 d3.nest 的对象,则有两件重要的事情:

  1. 您想要使用 nest.object(),而不是 nest.entries(),因为您需要嵌套对象,而不是嵌套数组;
  2. nest.rollup() 将替换嵌套值数组,这是预期的行为。因此,为了按照您想要的方式获取平均值,您必须指定 nest.rollup() 将返回的数组。在下面的演示中,我将使用上面使用的相同的reduce。

这是使用d3.nest的演示:

data = [{
day: "mon",
amount: "4",
month: "jan"
},
{
day: "tue",
amount: "2",
month: "jan"
},
{
day: "wed",
amount: "3",
month: "jan"
},
{
day: "wed",
amount: "1",
month: "jan"
}
];

const nested = d3.nest()
.key(d => d.month)
.rollup(v => v.reduce((a, b) => {
const found = a.find(d => d.day === b.day);
if (!found) {
a.push({
day: b.day,
avg_amount: +b.amount
})
} else {
found.avg_amount = (found.avg_amount + (+b.amount)) / 2
};
return a;
}, []))
.object(data);

console.log(nested)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

关于javascript - 通过对记录进行分组来获取数组的映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54602711/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com