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

fp-ts中按索引数组分割数组及分区操作工具咨询

在fp-ts中按外部索引数组分区后,如何便捷操作子数组?

作为fp-ts新手,你需要的是能按外部索引数组将原数组分区,并且让map、foldMap这类函数可以直接作用于分区子数组的方案。先看你的示例场景:

const x = ["a", "b", "c", "d", "e", "f"];
const p = [0, 0, 1, 2, 1, 0];

const partition = (partion: number[]) => (x: any[]) => {
  return x.reduce((result, nextValue, index) => {
    if (!(partion[index] in result)) result[partion[index]] = [];
    result[partion[index]].push(nextValue);
    return result;
  }, {});
};

const xPartitioned = partition(p)(x);
const shout = (x: string) => x.toUpperCase() + `!`;

// 当前可行的写法
const res1 = R.map(A.map(shout))(xPartitioned); 

// 期望的简化写法
const res2 = P.map(shout)(xPartitioned)

解决方案

fp-ts本身没有直接提供针对「键到数组」这种结构的高阶操作工具,但你可以通过两种方式实现需求:

1. 自行封装工具对象(最贴合你的预期)

直接封装你设想的P对象,还可以扩展其他需要的方法,比如foldMap:

import * as R from 'fp-ts/Record'
import * as A from 'fp-ts/Array'
import { Monoid } from 'fp-ts/Monoid'

const P = {
  // 给每个子数组的元素执行map操作
  map: <A, B>(fn: (a: A) => B) => (record: Record<string, A[]>) => 
    R.map(A.map(fn))(record),
  
  // 扩展foldMap:对每个子数组执行foldMap
  foldMap: <M>(M: Monoid<M>) => <A>(fn: (a: A) => M) => (record: Record<string, A[]>) =>
    R.map(A.foldMap(M)(fn))(record)
}

这样就能直接用P.map(shout)(xPartitioned)得到你想要的结果。

2. 利用fp-ts的函子组合性

Record<string, _>和Array<_>都是fp-ts中的Functor,它们的组合自然也是一个Functor,你可以基于这个抽象来定义操作,本质和上面的封装逻辑一致,只是更贴合fp-ts的函数式风格。

额外优化:用fp-ts风格实现分区逻辑

你自己写的partition函数可以用fp-ts内置方法优化,利用Array.zip和Array.groupBy实现更简洁的分区:

import * as A from 'fp-ts/Array'
import { pipe } from 'fp-ts/function'

const x = ["a", "b", "c", "d", "e", "f"];
const p = [0, 0, 1, 2, 1, 0];

// 基于外部索引数组分组的fp-ts风格实现
const partitionByIndices = <A>(indices: number[]) => (xs: A[]) =>
  pipe(
    A.zip(xs, indices), // 将元素与对应索引配对
    A.groupBy(([_, idx]) => String(idx)) // 按索引字符串作为键分组
  )

const xPartitioned = partitionByIndices(p)(x)

内容的提问来源于stack exchange,提问作者Adam B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:45:44