函数式编程javascript链过滤操作默认值

时间:2018-05-22 04:44:09

标签: javascript functional-programming

有没有办法过滤数组,如果它没有返回任何对象默认为单个链中的默认选项?

e.g。

[1,2,3]
    .filter(isDivisibleByTen)
    // otherwise return whatever

我可以像这样写

const result [1,2,3].filter(isDivisibleByTen) 
result ? result [0]

4 个答案:

答案 0 :(得分:1)

以下是我认为您在一行中寻找的内容,但如果结果为false,则filter()将不返回任何内容。在演示1中使用了filter()。在演示2 map()中使用返回任意值"default"作为备用返回。

<小时/>

演示1

<小时/>
&#13;
&#13;
console.log([1, 21, 30].filter(a => a % 10 === 0));
&#13;
&#13;
&#13;

演示2

<小时/>
&#13;
&#13;
console.log([1,21,30].map(a => a % 10 === 0 ? a : 'default'));
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您可以尝试reduce()。这允许您传递初始值(默认返回值),然后如果它们通过测试则将值添加到返回数组。因此,如果没有值通过测试,该函数将返回默认值。

&#13;
&#13;
console.log([1,21,30].reduce((t, v) => { return v % 10 === 0 ? (t = 'default' ? [v] : t.concat(v)) : t; }, 'default'))
&#13;
&#13;
&#13;

&#13;
&#13;
    console.log([1,21,35].reduce((t, v) => { return v % 10 === 0 ? (t = 'default' ? [v] : t.concat(v)) : t; }, 'default'))
&#13;
&#13;
&#13;

答案 2 :(得分:1)

解决方案1.无副作用。

也许reduce是提供数组的唯一Array方法,可以返回任意值,以便您可以使用它:

[1,2,3]
    .filter(isDivisibleByTen)
    .reduce((_1, _2, _3, array) => array, 'defaultValue');

这个解决方案浪费了一点点处理器(在数组上循环没有任何好处),但它可以轻松地与任何链组合。

解决方案2.优雅的解决方案。

您可以向Array原型添加自定义方法,使其在链中可用:

Array.prototype.filledOrDefault = function(defaultValue) {
    return this.length ? this : defaultValue;
}

[1,2,3]
    .filter(isDivisibleByTen)
    .filledOrDefault('defaultValue');

建议不要使用此解决方案,因为它会修改页面上其他脚本使用的全局值(Array)。

答案 3 :(得分:0)

我在这里添加一个更详细的选项。该解决方案使用3个纯函数,然后将其组合在一个管道中。这是函数式编程的典型特征,并且具有能够单独测试函数以确保它们完全符合您的要求的附带好处。

(作为侧边栏,其他语言如elixir使链接更符合语法,但我离题了)

&#13;
&#13;
const defaultValue = "foobar";

const isDivisibleBy10 = n => n % 10 === 0;

const enforceDefault = numbers => numbers.length ? numbers : [defaultValue];

const unpackSingleton = numbers => numbers.length === 1 ? numbers[0] : numbers;


const pipeline = numbers =>
  unpackSingleton(
    enforceDefault(
      numbers.filter(isDivisibleBy10)
    )
  )

console.log(pipeline([2])); // no matches so returns default
console.log(pipeline([20])) // one match so returns the item

console.log(pipeline([1, 20, 10, 3])) // general case
&#13;
&#13;
&#13;