javascript - 如何通过函数式编程在一个公共键上合并 N 个元组数组?
问题描述
我有 3 个数组,它们都包含元组。第一个值是时间戳 (ts),第二个是当时发生的事件计数。单个数组根据时间戳进行排序。
var arr1 = [{ts: 1000, val: 1},{ts: 1001, val: 2},{ts: 1002, val: 3}];
var arr2 = [{ts: 1001, val: 4},{ts: 1002, val: 5},{ts: 1005, val: 6}];
var arr3 = [{ts: 1003, val: 8},{ts: 1007, val: 8},{ts: 1008, val: 8}];
我想将它们合并到一个时间线中,在一个 4xN 数组中,这样它就变成了:
[
[1000, 1, 0, 0],
[1001, 2, 4, 0],
[1002, 3, 5, 0],
[1003, 0, 0, 8],
[1005, 0, 6, 0],
[1007, 0, 0, 8],
[1008, 0, 0, 8],
]
其中第一列是时间戳,第二列是第一个数组值,第三列是第二个数组值...
我试图以非功能性的方式来做,但无法提出一个优雅清晰的解决方案,它不涉及重复查找数组中的时间戳以找到相应的值。我觉得应该有一种相对简单的方法可以在功能上做到这一点,因为我基本上是将基于行的数据转换为列式数据。
如果为 N 个数组解决它是有问题的,我也可以使用 3 个数组的解决方案!
解决方案
我没有看到比您丢弃的在数组中查找时间戳的概念更好的了。如果数据真的很大,那么您可以对其进行索引。但是代码不太可能是漂亮的。
这是一个 ES6 版本:
const extract = (...xss) =>
[... new Set (xss .flatMap (xs => xs .map (x => x .ts)))]
.map (t => [t, ... xss .map (xs => (xs.find(({ts}) => t == ts) || {val: 0}).val)])
const arr1 = [{ts: 1000, val: 1}, {ts: 1001, val: 2}, {ts: 1002, val: 3}];
const arr2 = [{ts: 1001, val: 4}, {ts: 1002, val: 5}, {ts: 1005, val: 6}];
const arr3 = [{ts: 1003, val: 8}, {ts: 1007, val: 8}, {ts: 1008, val: 8}];
console .log (extract (arr1, arr2, arr3))
.as-console-wrapper {max-height: 100% !important; top: 0}
至于 Ramda,我们当然可以在这里使用 Ramda。第一行可以替换为
uniq (chain (pluck ('ts')) (xss))
我们可以类似地用 Ramda 等价物替换map
s 和,我们可以用 a代替. 如果您使用 Ramda,您可能可以继续这种方式一段时间,我强烈建议您尝试一下。但我认为,如果您正在寻找一个完全无点的解决方案,它很可能很快就会变得不可读。find
defaultTo
|| {val: 0}
推荐阅读
- angular - Angular 6拦截器:更改响应内容类型
- c# - 将 XML 添加到包含数组 C# 的字典中
- python - 从 [-1; 转换图像;1] 到 [0; 255]
- r - 在 Shiny Dashboard 中同时加载所有页面
- c# - 如何从 C# .net 核心中的动态 json 对象读取数据
- python - 查询具有列表值的 pandas 数据框列
- python - 如何从文本文件中读取列表,该文件位于python中某些文本的下方?
- java - 如何在Java中解密字符串中的加密消息
- wpf - 如何捕获并优雅地处理 WPF 中数据库不可用的异常
- oracle - sql loader 不使用数据库密码