通过几个函数映射数组项

5

有没有更加优雅的方法来对数组中的每个元素依次执行多个函数:

type Transform<T> = (o: T) => T;
type Item = { /* properties */ };

transform(input, transformers: Transform<Item>[]) {
  const items: Item[] = getItems(input);
  return items.map(item => {
    let transformed = item;
    tramsformers.forEach(t => transformed = t(transformed));
    return transformed;
  })
}

1
定义“优雅”。 - T.J. Crowder
我不喜欢那个本地变量,但 forEach() 返回 void。不确定如何将转换的结果传递给下一个变量。 - Sasxa
2个回答

6
这是一个很好的使用 reduce 的案例:
transform(input, transformers: Transform<Item>[]) {
  const items: Item[] = getItems(input);
  return items.map(item => transformers.reduce((val, transformer) => transformer(val), item));
}

也许更易读的方式是:
transform(input, transformers: Transform<Item>[]) {
  const items: Item[] = getItems(input);
  return items.map(
    item => transformers.reduce(
      (val, transformer) => transformer(val),
      item
    )
  );
}

实时示例:

function getItems(input) {
  return [
    "abcdefg",
    "1234567"
  ];
}
function transform(input, transformers) {
  const items = getItems(input);
  return items.map(item => transformers.reduce((val, transformer) => transformer(val), item));
}
const result = transform("x", [
  v => v.toUpperCase(),
  v => v.substring(1, v.length - 1)
]);
console.log(result);

正如Nitzan Tomer所指出的那样,我们可以取消items常量:
transform(input, transformers: Transform<Item>[]) {
  return getItems(input).map(
    item => transformers.reduce(
      (val, transformer) => transformer(val),
      item
    )
  );
}

我经常保留这些东西用于调试,但现在一些好的调试器让在函数返回之前查看其返回值变得更加容易(例如Chrome的调试器),因此,如果您删除了它,你可以进入getItems函数并在执行map操作之前查看项目。


这里也不需要 items 常量,可以在没有它的情况下成为一行代码。 - Nitzan Tomer
@NitzanTomer:确实,这不是必要的,但我认为这不是问题的重点。(对于我的代码,我可能会将其保留在那里以使调试更容易;它最终会被优化掉。) - T.J. Crowder

0

这是一个更加可重用的版本,基于@T.J.Crowder的答案:

export type Transform<T> = (o: T) => T;
export function pipe<T>(sequence: Transform<T>[] = []) {
  return (item: T) => sequence.reduce((value, next) => next(value), item);
}

transform(input, transformers?) {
  return getItems(input).map( pipe(transformers) );
}

请注意,类型是从getItems(input)中推断出来的,并且返回类型是transform():Item[]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接