首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用fp-ts删除数组中的重复项

使用fp-ts删除数组中的重复项
EN

Stack Overflow用户
提问于 2020-04-19 15:30:08
回答 1查看 829关注 0票数 0

在使用fp-ts的函数式编程中,删除任一数组的重复项的最佳方法是什么

这是我的尝试:

代码语言:javascript
复制
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>[]
    )
);

Playground link

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-25 04:35:30

通常,在fp-ts中,您可以使用Array<A>中的uniqfp-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>>。在您的情况下,ER是相同的(即IItem),所以您只需使用同一个Eq<IItem>实例两次。

最有可能的是,您需要的Eq<IItem>实例将如下所示:

代码语言:javascript
复制
// 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>>进行重复数据删除:

代码语言:javascript
复制
// 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>>定义的“相等”的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61300952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档