我有一些原始国家/地区和开始时间数据 - 列在这样的数据中
我尝试使用的库是 ramda https://jsfiddle.net/0kdcvahw/
var data = [
{
"label": "Argentina",
"isIncluded": true,
"times": [
{"text": "", "starting_time": Date.parse('2020-01-14T10:00:00Z'), "ending_time": Date.parse('2020-02-14T15:20:00Z')}
]
},
{
"label": "Chile",
"isIncluded": true,
"times": [
{"text": "", "starting_time": Date.parse('2020-01-14T10:00:00'), "ending_time": Date.parse('2020-05-20T03:24:00')}
]
},
{
"label": "United States of America",
"isIncluded": true,
"times": [
{"text": "", "starting_time": Date.parse('2020-01-14T11:00:00Z'), "ending_time": Date.parse('2020-03-20T03:24:00')}
]
}
];
我想重新配置列表,使其更像这样
var data = [
{
label: 'Argentina, Chilie',
value: 90,
},
{
label: 'United States',
value: 10,
}
];
所以基本上 - 有 3 个国家 --- 其中 2 个在同一天和相同的开始时间开始,例如10:00。 - 1 于同一天开始,但 11:00
<小时/>代码示例 - 但需要删除最后一个逗号
var data = [
{
"label": "Argentina",
"isIncluded": true,
"times": [
{"text": "", "starting_time": Date.parse('2020-01-14T10:00:00Z'), "ending_time": Date.parse('2020-02-14T15:20:00Z')}
]
},
{
"label": "Chile",
"isIncluded": false,
"times": [
{"text": "", "starting_time": Date.parse('2020-01-14T10:00:00'), "ending_time": Date.parse('2020-05-20T03:24:00')}
]
},
{
"label": "United States of America",
"isIncluded": true,
"times": [
{"text": "", "starting_time": Date.parse('2020-01-14T11:00:00Z'), "ending_time": Date.parse('2020-03-20T03:24:00')}
]
}
];
//console.log("data",data);
const groups = R.groupBy(x => x.times[0].starting_time, data);
const newData = Object.keys(groups).map(key => {
return {
label: groups[key].reduce((c, n) => `${c}${n.label}, `, ''),
value: groups[key].length
}
})
console.log('newData', newData)
最佳答案
这是 Ramda 方法:
const transform = pipe (
groupBy (path (['times', 0, 'starting_time'])),
values,
map (applySpec ({
label: pipe (pluck ('label'), join (', ')),
value: length
}))
)
const data = [{"isIncluded": true, "label": "Argentina", "times": [{"ending_time": 1581693600000, "starting_time": 1578996000000, "text": ""}]}, {"isIncluded": false, "label": "Chile", "times": [{"ending_time": 1589945040000, "starting_time": 1578996000000, "text": ""}]}, {"isIncluded": true, "label": "United States of America", "times": [{"ending_time": 1584674640000, "starting_time": 1578999600000, "text": ""}]}]
console .log (transform (data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script>const {pipe, groupBy, path, values, map, applySpec, pluck, join, length} = R</script>
我假设某些日期缺少最后的“Z”
这一事实只是一个拼写错误。如果有些人应该有它而其他人没有,那么你就会有一些非常奇怪的数据,并且它与你提供的输出不匹配,除非你碰巧住在那个时区的地方。
之后,Ramda 的代码就相当简单了。 groupBy
采用一个函数,为您提供该项目的规范键。这里我们将 path
的结果传递给它。 path
接受一个字符串或整数数组,并返回一个函数,该函数将返回输入对象的该路径处的值,如果任何节点不存在,则返回未定义的值。 groupBy (fn)
返回一个对象,该对象在找到的每个规范键处都有一个数组,输入数组中的项目被划分到这些数组中。
我们对该结果调用values
,这只不过是对Object.values
的引用;它返回一个数组的数组。
在每个外部数组上(通过map
),我们调用applySpec
,它接受键到函数的映射,使用这些键创建一个对象,其值是将相应函数应用于输入值的结果。对于value
,我们只返回底层数组的length
,对于label
,我们从其中提取label
条目每个对象,然后用 ", "
连接它们。
在这里的答案中,我经常展示现代 JS 如何使某些 Ramda 函数变得不那么引人注目。虽然我可以在这里通过将一些简单的 ES6+ 替代方案组合到 applySpec
和 values
中,使用简单的 lambda 表示 length
并替换 pipeline (pluck ('label'), join (', ')
类似 arr => arr .map (item => item .label) .join (', ')
。但我不打扰,因为我们仍然必须编写一个与 groupBy
等效的一次性代码。虽然这并不困难,但我认为代码会比这长得多。而且我不知道没有看到它有什么收获。当然,如果我还没有在我的项目中使用 Ramda,我当然会这样做,但总的来说,这感觉是使用 Ramda 简化的好时机。
关于javascript - Ramda lib - javascript - 数据重构/分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59899569/