更优雅的方式来获得过滤价值?

时间:2016-10-07 22:11:50

标签: javascript arrays object functional-programming

我有一个函数,它根据对象中的字符串返回过滤结果(如果存在与否)

let foo = nodes.reduce((arr, cur) => {
    cur.classes.split(' ').filter((el) => {
        if (el === 'foo') arr.push(cur)
    })
    return arr; 
}, []);

所以它只返回数组中包含'object'中'foo'的所有对象 这个,例如:

let nodes = [
  {node: 'h1', classes: 'foo'},
  {node: 'p', classes: 'bar'},
  {node: 'p', classes: 'baz xxx'},
  {node: 'h2', classes: 'bar baz foo'},
  {node: 'ul', classes: 'poop foo'}
]

但我的胆量告诉我,这个功能可以更容易,更简洁地写出来。有什么想法吗?

3 个答案:

答案 0 :(得分:5)

您可以只使用Array#filter



let nodes = [{node: 'h1', classes: 'foo'}, {node: 'p', classes: 'bar'}, {node: 'p', classes: 'baz xxx'}, {node: 'h2', classes: 'bar baz foo'}, {node: 'ul', classes: 'poop foo'}],
    foo = nodes.filter(a => a.classes.split(' ').some(b => b === 'foo'));

console.log(foo);




答案 1 :(得分:1)

按照惯例,@ NinaScholz提供了一种非常直接的方法。根据她的建议,你会很富裕。

我个人希望进一步剖析这些问题,并演示如何组合较小的可重复使用的功能以实现所需的效果。我希望这个答案可以帮助您看到JavaScript中的函数式编程可以轻松扩展到内置的原型方法之外。

评论可以帮助您理解类型,但完全是可选的。

// comp :: (b -> c) -> (a -> b) -> (a -> c)
const comp = f => g => x => f (g (x));

// filter :: (a -> Boolean) -> [a] -> [a]
const filter = f => xs => xs.filter(f);

// some :: (a -> Boolean) -> [a] -> Boolean
const some = f => xs => xs.some(f);

// eq :: (String a, Number a) => a -> a -> Boolean 
const eq = x => y => y === x;

// nodeClasses :: Node -> [String]
const nodeClasses = ({classes}) => classes.split(' ');

// nodesWithClass :: String -> [Node] -> [Node]
const nodesWithClass = c => filter (comp (some (eq (c))) (nodeClasses));

// nodes :: [Node]
let nodes = [
  {node: 'h1', classes: 'foo'},
  {node: 'p', classes: 'bar'},
  {node: 'p', classes: 'baz xxx'},
  {node: 'h2', classes: 'bar baz foo'},
  {node: 'ul', classes: 'poop foo'}
];

console.log(nodesWithClass('foo') (nodes));

答案 2 :(得分:0)

作为替代"过滤一些",如Nina所示,一种稍微不同的方法。

看起来不干净,但性能更高(就如此简单的任务而言,性能至关重要)。

let nodes = [
  {node: 'h1', classes: 'foo'},
  {node: 'p', classes: 'bar'},
  {node: 'p', classes: 'foo-bar'},
  {node: 'p', classes: 'baz xxx'},
  {node: 'h2', classes: 'bar baz foo'},
  {node: 'ul', classes: 'poop foo'}
];

let foo = nodes.filter(node => (' ' + node.classes + ' ').contains(' foo '));