Javascript 使用fp ts删除任意一个的数组中的重复项

Javascript 使用fp ts删除任意一个的数组中的重复项,javascript,typescript,functional-programming,fp-ts,Javascript,Typescript,Functional Programming,Fp Ts,在使用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 =

在使用
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>[]
    )
);
import{作为E,作为P}从“fp-ts”导入;
从“fp ts/lib/function”导入{flow};
接口项{
类型:“有效”|“无效”;
值:字符串;
}
//建立一些虚假数据
const buildItem=(值?:字符串):E.或=>
价值!=无效的E.right(value):E.left({type:“INVALID”,value:“});
//我们将始终有一个数组
常数项=[
建筑项目(“aa”),
建筑项目(“ab”),
buildItem(),
建筑项目(“ac”),
建筑项目(“ab”),
建筑项目(“ac”),
buildItem(),
建筑项目(“aa”)
];
常量检查表:字符串[]=[];
导出常量程序=流(
()=>项目,
x=>
x、 减少(
(附件,项目)=>
管道(
项目,,
E.chain(值=>{
if(检查表索引(值)<0){
检查表。推送(值);
返回E.right({type:“VALID”,value:value}作为IItem);
}
返回E.left({type:“INVALID”,value:value}作为IItem);
}),
v=>acc.concat(v)
),
[]作为,例如
)
);

通常,在
fp-ts
中,您可以使用
fp-ts/lib/Array
中的
uniq
数组中删除重复项。给定一个
Eq
和一个
数组
,它将返回一个
数组
,其中所有
A
都是唯一的

在您的情况下,似乎需要对
数组进行重复数据消除。这意味着,为了使用
uniq
,您需要
Eq
的一个实例。获取的方法是使用
getEq
from
fp-ts/lib/or
。它要求您为您的
参数化的每种类型提供
Eq
实例,一个用于左侧案例,另一个用于右侧案例。因此,对于
getEq
将取
Eq
Eq
并给您一个
Eq
。在您的情况下,
E
R
是相同的(即
IItem
),因此您只需使用相同的
Eq
实例两次

您想要的
Eq
实例很可能如下所示:

// 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
})
// 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
常量将是一个
数组
,其中没有两个
是由
Eq
定义的“相等的”

通常,在
fp ts
中,您可以使用
uniq
fp ts/lib/Array
中删除
数组中的重复项。给定一个
Eq
和一个
数组
,它将返回一个
数组
,其中所有
A
都是唯一的

在您的情况下,似乎需要对
数组进行重复数据消除。这意味着,为了使用
uniq
,您需要
Eq
的一个实例。获取的方法是使用
getEq
from
fp-ts/lib/or
。它要求您为您的
参数化的每种类型提供
Eq
实例,一个用于左侧案例,另一个用于右侧案例。因此,对于
getEq
将取
Eq
Eq
并给您一个
Eq
。在您的情况下,
E
R
是相同的(即
IItem
),因此您只需使用相同的
Eq
实例两次

您想要的
Eq
实例很可能如下所示:

// 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
})
// 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
常量将是一个
数组
,其中没有两个
或者
是由
Eq
定义的“相等的”

那么使用
.filter()
来消除重复项和
.map()
来返回一个新形成的列表呢?我希望在这里使用某种形式的非此即彼或选项。我想我必须用这些来更新这个问题。啊,好的,明白了!我可以给你一个基本的地方,让你从纯JS开始,如果它有效的话?当然@weirdpanda,请继续。我将尝试更新这个问题,以获得更好的可视性和澄清。@AminPaks,上面的代码片段与您提出的问题之间的关系还不完全清楚。我认为,如果您删除代码并仅使用类型而不是实现来提问,我的问题会更清楚。似乎
uniq(eqString)(items.filter(notNull))
是您真正需要的,但您的问题是关于reduce的。Reduce对于您正在做的事情来说似乎不是必需的。使用
.filter()
来消除重复项,使用
.map()
来返回新的格式列表怎么样?我希望在这里使用某种类型的或选项。我想我必须用这些来更新这个问题。啊,好的,明白了!我可以给你一个基本的地方,让你从纯JS开始,如果它有效的话?当然@weirdpanda,请继续。我将尝试更新这个问题,以获得更好的可视性和澄清。@AminPaks,上面的代码片段与您提出的问题之间的关系还不完全清楚。我认为,如果您删除代码并仅使用类型而不是实现来提问,我的问题会更清楚。似乎
uniq(eqString)(items.filter(notNull))
是您真正需要的,但您的问题是关于reduce的。Reduce对于您正在做的事情似乎不是必需的。它表明fp ts v2中没有getStruct。我想我理解了getEq的用法,并将其与eqString混合使用。唯一的问题是,如果是,我需要使用eqStruct吗?我应该从哪里导入它?@AminPaks,对不起。那是个打字错误。修正了。它表明fp ts v2中没有getStruct。我想我理解了getEq的用法,并将其与eqString混合使用。唯一的问题是,如果是,我需要使用eqStruct吗?我应该从哪里导入它?@AminPaks,对不起。那是个打字错误。固定的。