Ramda.js:如何对集合的子集应用函数?
Great question! The issue with your current implementation is that splitting and concatenating the collection disrupts the original order. In functional programming—especially with Ramda.js—we can solve this more elegantly without rearranging elements.
Core Idea
Instead of splitting the collection into two parts, modifying one, then recombining, we can traverse each element individually and apply the function only when the predicate is satisfied. This keeps the original order intact and avoids redundant filtering.
Ramda.js Implementation
Ramda provides when, a function that applies a transformation to a value if it meets a predicate, otherwise returns the value as-is. Combining this with map gives us exactly what we need:
const applyToSubset = R.curry((fn, predicate, col) => R.map(R.when(predicate, fn), col) );
How to Use It
Let’s test this with an example: say we want to add 1 to all numbers greater than 2 in an array:
const result = applyToSubset(R.add(1), R.gt(R.__, 2), [1, 2, 3, 4]); // Result: [1, 2, 4, 5] (order is preserved!)
Ramda’s auto-currying also lets us partially apply arguments for reusability:
const incrementLargeNumbers = applyToSubset(R.add(1), R.gt(R.__, 2)); incrementLargeNumbers([5, 1, 3, 0]); // [6, 1, 4, 0]
Pure JavaScript Functional Alternative
If you don’t want to rely on Ramda, you can achieve the same effect with vanilla JS using map:
const applyToSubset = (fn) => (predicate) => (col) => col.map(item => predicate(item) ? fn(item) : item);
This works exactly the same way—traversing each element, applying the function only when the predicate passes, and preserving the original order.
Why This Is Better Than Your Original Approach
- Preserves order: No splitting/concatenating means elements stay in their original positions.
- More efficient: Only iterates over the collection once (instead of twice for filtering, plus a concat).
- Cleaner, declarative code: The intent is clear—"map over the collection, apply fn to items that match the predicate"—without low-level array manipulation.
内容的提问来源于stack exchange,提问作者mac

