问题
I have an array of unique values:
const array = [1, 2, 4]
I have a collection of unique objects:
const collection = [
{ type: 1, eyes: 'blue'},
{ type: 2, eyes: 'brown'},
{ type: 3, eyes: 'green'},
{ type: 4, eyes: 'blue'}
]
Using Ramda how do I extract all the objects from collection
where type is included in array
?
Expected outcome:
[
{ type: 1, eyes: 'blue'},
{ type: 2, eyes: 'brown'},
{ type: 4, eyes: 'blue'}
]
回答1:
Use R.innerJoin():
const array = [1, 2, 4]
const collection = [{ type: 1, eyes: 'blue'},{ type: 2, eyes: 'brown'}, { type: 3, eyes: 'green'}, { type: 4, eyes: 'blue'}]
const joinByType = R.innerJoin(
(o, type) => o.type === type
)
const result = joinByType(collection, array)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
The same method in a more ramdaish way using R.propEq() to compare the type
property with the type id from the array. We need to use R.flip() because innerJoin passes the object before the the value to compare to.
const array = [1, 2, 4]
const collection = [{ type: 1, eyes: 'blue'},{ type: 2, eyes: 'brown'}, { type: 3, eyes: 'green'}, { type: 4, eyes: 'blue'}]
const joinByType = R.innerJoin(R.flip(R.propEq('type')))
const result = joinByType(collection, array)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
回答2:
Without ramda
collection.filter(item => array.includes(item.type))
回答3:
I think the answer from Mukesh Soni is what you need for this. In Ramda, it might read filter(p => array.includes(p.type), collection)
, but that's much the same.
But Ramda is all about functions, and creating reusable and flexible functions to handle your needs. I would at least consider writing something like this:
const {curry, filter, contains, prop} = R
const collection = [{ type: 1, eyes: 'blue'},{ type: 2, eyes: 'brown'}, { type: 3, eyes: 'green'}, { type: 4, eyes: 'blue'}]
const array = [1, 2, 4]
const filterBy = curry((propName, selectedValues, collection) =>
filter(e => contains(prop(propName, e), selectedValues), collection))
const newCollection = filterBy('type', array, collection)
console.log(newCollection)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
I might even go one step further, and allow for an arbitrary transformation function, rather than just prop
:
const filterBy = curry((transform, selectedValues, collection) =>
filter(e => selectedValues.includes(transform(e)), collection))
filterBy(prop('type'), array, collection)
But abstractions such as these are generally only helpful if you expect to make other use of them across your application. If this is the only place where you use a list of values to match with in order to filter a collection, then there is little reason for any reusable function.
来源:https://stackoverflow.com/questions/50161078/filter-collection-based-on-values-in-array-in-ramda