Functional programming fp ts:基于下一个元素的筛选器数组

Functional programming fp ts:基于下一个元素的筛选器数组,functional-programming,fp-ts,Functional Programming,Fp Ts,我从函数式编程开始/fp ts。 我试图编写一个函数,如果下一个元素的条件得到满足,它将以列表的形式保留一个元素 例如: const condition = (i: number) => i % 10 === 0; filterNext(condition, [19, 20, 3, 18, 8, 48, 20, 4, 10]) // => [3, 4] 我可能还需要扩展它,以便同时包含匹配项和下一个元素,如下所示: const condition = (i: number) =&g

我从函数式编程开始/
fp ts
。 我试图编写一个函数,如果下一个元素的条件得到满足,它将以列表的形式保留一个元素

例如:

const condition = (i: number) => i % 10 === 0;
filterNext(condition, [19, 20, 3, 18, 8, 48, 20, 4, 10]) // => [3, 4]
我可能还需要扩展它,以便同时包含匹配项和下一个元素,如下所示:

const condition = (i: number) => i % 10 === 0;
filterNext(condition, [19, 20, 3, 18, 8, 48, 90, 4, 10]) // => [10, 3, 90, 4, 10]
我不知道如何为这两个函数中的任何一个构建一个合适的纯函数


欢迎提供任何提示。

让我知道这是否有效

import {Predicate, Refinement} from 'fp-ts/lib/function'
import {filterWithIndex} from 'fp-ts/lib/Array'
function filterWithNext<A>(predicate: Predicate<A>, xs: Array<A>): Array<A>
function filterWithNext<A, B extends A>(
  predicate: Refinement<A, B>,
  xs: Array<A>
): Array<B> {
  return filterWithIndex<A, B>(
    (i, x): x is B => predicate(x) && i !== xs.length && predicate(xs[i + 1])
  )(xs)
}
从'fp ts/lib/function'导入{谓词,求精}
从“fp ts/lib/Array”导入{filterWithIndex}
函数filterWithNext(谓词:谓词,xs:Array):数组
函数过滤器WithNext(
谓词:求精,
xs:Array
):数组{
返回过滤器HITINDEX(
(i,x):x是B=>谓词(x)&&i!==xs.length&&predicate(xs[i+1])
)(xs)
}

首先,让我向您展示代码:

import * as O from "fp-ts/lib/Option";
import * as A from "fp-ts/lib/Array";
import { pipe } from "fp-ts/lib/pipeable";

const filterOnPrevious = <T>(condition: (T) => boolean, xs: T[]): T[] =>
  pipe(
    A.tail(xs),
    O.getOrElse<T[]>(() => []),
    tail => A.zip(tail, xs),
    A.filter(([_, x]) => condition(x)),
    A.map(([x]) => x)
  );
import*作为O从“fp ts/lib/Option”导入;
从“fp ts/lib/Array”将*导入为A;
从“fp ts/lib/pipeable”导入{pipe};
常量filterOnPrevious=(条件:(T)=>boolean,xs:T[]):T[]=>
烟斗(
A.tail(xs),
O.getOrElse(()=>[]),
tail=>A.zip(tail,xs),
A.过滤器(([[ux])=>条件(x)),
A.map(([x])=>x)
);
第二,您编写了“如果满足了下一个元素的条件”,但您的示例显示该条件应该传递给上一个。该代码用于您的示例

这项任务包括三个部分:

  • 为过滤器准备数据
  • 过滤器
  • 提取您需要的内容
  • 神奇的功能是从两个数组中创建对

    我使用原始数组和移位(删除第一个元素)数组运行它。这将创建对,其中对中的第一个值是原始值,第二个值是应运行条件的值

    因为
    Array.tail
    返回一个选项(如果数组为空,则返回none),所以我们需要首先通过
    Option.getOrElse
    运行它

    在最后一步中,过滤这些对之后,我映射它们并从每个对中获取原始值

    当我使用一对时,你可以使用一个对象或其他结构。我喜欢成对的,因为由于数组的分解,它们很容易输入和使用

    如何改变行为:

    • filterOnNext:将
      A.zip(尾部,xs)
      切换到
      A.zip(尾部,xs)
      。同样,第一个值是原始值,第二个值是应该运行条件的值。或者,更新
      A.filter
      A.map
      ,使其使用该对中的其他值
    • 同时保留两个:这很棘手,因为如果一行中的三个数字满足条件,则不清楚期望的结果是什么。无论如何,我仍然建议首先创建一对,如果条件传递给第二个值,则结果是一个值

    如果需要前瞻语义,通常必须求助于递归。也许有一个奇特的递归方案(fold),但我不知道。