我有一个函数,它根据对象中的字符串返回过滤结果(如果存在与否)
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'}
]
但我的胆量告诉我,这个功能可以更容易,更简洁地写出来。有什么想法吗?
答案 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 '));