在使用fp-ts的函数式编程中,删除任一数组的重复项的最佳方法是什么
这是我的尝试:
import { either as E, pipeable as P } from "fp-ts";
import { flow } from "fp-ts/lib/function";
interface IItem {
type: "VALID" | "INVALID";
value: string;
}
// Building some fake data
const buildItem = (value?: string): E.Either<unknown, string> =>
value != null ? E.right(value) : E.left({ type: "INVALID", value: "" });
// We will always have an array of Either
const items = [
buildItem("aa"),
buildItem("ab"),
buildItem(),
buildItem("ac"),
buildItem("ab"),
buildItem("ac"),
buildItem(),
buildItem("aa")
];
const checkList: string[] = [];
export const program = flow(
() => items,
x =>
x.reduce(
(acc, item) =>
P.pipe(
item,
E.chain(value => {
if (checkList.indexOf(value) < 0) {
checkList.push(value);
return E.right({ type: "VALID", value: value } as IItem);
}
return E.left({ type: "INVALID", value: value } as IItem);
}),
v => acc.concat(v)
),
[] as E.Either<unknown, IItem>[]
)
);发布于 2020-04-25 04:35:30
通常,在fp-ts中,您可以使用Array<A>中的uniq从fp-ts/lib/Array中删除重复项。给定一个Eq<A>和一个Array<A>,它将返回一个Array<A>,其中所有A都是唯一的。
在您的案例中,您似乎希望对Array<Either<IItem, IItem>>进行重复数据删除。这意味着,为了使用uniq,您将需要一个Eq<Either<IItem, IItem>>实例。获得它的方法是使用fp-ts/lib/Either中的getEq。它要求您为Either的每个参数化类型提供一个Eq实例,一个用于左边的情况,另一个用于右边的情况。因此对于Either<E, R>,getEq将获取一个Eq<E>和一个Eq<R>,并为您提供一个Eq<Either<E, R>>。在您的情况下,E和R是相同的(即IItem),所以您只需使用同一个Eq<IItem>实例两次。
最有可能的是,您需要的Eq<IItem>实例将如下所示:
// IItem.ts |
//-----------
import { Eq, contramap, getStructEq, eqString } from 'fp-ts/lib/Eq'
export interface IItem {
type: "VALID" | "INVALID";
value: string;
}
export const eqIItem: Eq<IItem> = getStructEq({
type: contramap((t: "VALID" | "INVALID"): string => t)(eqString),
value: eqString
})一旦你有了它,你就可以像这样用uniq对你的Array<Either<IItem, IItem>>进行重复数据删除:
// elsewhere.ts |
//---------------
import { array, either } from 'fp-ts'
import { Either } from 'fp-ts/lib/Either'
import { IItem, eqIItem } from './IItem.ts'
const items: Array<Either<IItem, IItem>> = []
const uniqItems = uniq(either.getEq(eqIItem, eqIItem))(items)uniqItems常量将是一个Array<Either<IItem, IItem>>,其中没有两个Either<IItem, IItem>是由Eq<Either<IItem, IItem>>定义的“相等”的。
https://stackoverflow.com/questions/61300952
复制相似问题