You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中使用Lodash合并多数组并对元素执行自定义计算

lodash/fp 按年份跨对象计算数值实现方案

你当前处理的是Record<string, number[][]>结构的多份数据集,需要按相同key下的匹配年份,对多份输入的数值执行自定义算术规则,示例规则为同一年份结果 = input1值 + input2值 - input3值,预期输出2002年结果25、2003年结果60。

你已经实现了单key下的数值提取,得到按输入分组的数值矩阵:

map(a => a.map(nth(1)))(map('key1')([input1, input2, input3]))
// 返回值 [[10, 50], [20, 70], [5, 60]]

之前使用zip/zipWith未得到预期结果,核心原因是没有做矩阵转置:你拿到的矩阵第一维度是输入来源,第二维度是年份,需要先把维度互换,把同一年份的所有输入值归为一组,再执行计算。


具体实现

基础版:匹配当前示例需求

核心分三步:提取数值矩阵、转置矩阵按年份分组、执行自定义计算

import { map, nth, zip } from 'lodash/fp';

const inputs = [input1, input2, input3];
// 1. 提取key1下所有年份的纯数值,得到按输入分组的矩阵
const valueMatrix = map(item => item.key1.map(nth(1)))(inputs);
// 2. 转置矩阵,得到按年份分组的数值集合:[[10,20,5], [50,70,60]]
const yearValueGroups = zip(...valueMatrix);
// 3. 按规则计算每个年份的结果
const result = map(([val1, val2, val3]) => val1 + val2 - val3)(yearValueGroups);
// 输出 [25, 60],和预期完全一致

如果需要保留年份和值的映射关系,只需要在提取阶段保留年份字段即可:

// 提取key1下的原始[年份, 值]对
const rawEntryMatrix = map('key1')(inputs);
// 转置后按年份分组
const yearGroups = zip(...rawEntryMatrix);
// 计算时保留年份标识
const resultWithYear = map(group => {
  const year = group[0][0];
  const calcVal = group[0][1] + group[1][1] - group[2][1];
  return [year, calcVal];
})(yearGroups);
// 输出 [[2002, 25], [2003, 60]]

通用封装版

可以把逻辑封装为可复用函数,支持任意数量输入、任意key、任意计算规则:

import { map, nth, zip } from 'lodash/fp';

/**
 * 按年份跨输入数据集计算数值
 * @param {Array} inputList 所有输入数据组成的数组
 * @param {string} targetKey 要计算的key名
 * @param {Function} calcFn 计算回调,入参为同一年份所有输入的数值组成的数组
 * @returns {Array} [年份, 计算结果] 组成的二维数组
 */
const calcAcrossInputs = (inputList, targetKey, calcFn) => {
  const entryMatrix = map(item => item[targetKey])(inputList);
  const yearGroups = zip(...entryMatrix);
  return map(group => {
    const currentYear = group[0][0];
    const yearValues = map(nth(1))(group);
    return [currentYear, calcFn(yearValues)];
  })(yearGroups);
};

// 调用示例
const finalResult = calcAcrossInputs(
  [input1, input2, input3],
  'key1',
  ([v1, v2, v3]) => v1 + v2 - v3
);

之前zipWith未生效的原因

zipWith本身完全可以实现这个需求,之前没拿到正确结果,大概率是没有正确传入展开后的矩阵和对应计算回调,正确写法如下:

import { zipWith } from 'lodash/fp';

// 一行完成转置+计算
const quickResult = zipWith((...values) => values[0] + values[1] - values[2])(...valueMatrix);
// 输出 [25, 60]

内容的提问来源于stack exchange,提问作者alik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:12:18