在对象中使用 ramda 函数搜索
Search using ramda functions in object
我有以下代码:
const trimString = (s) => s.trim()
const compareObjects = (o1, o2) => equals(o1, o2)
const itemExists = (haystack, needle) => contains(haystack, needle)
const objects = [
{ duration: '0.360000', name: 'Arthur', time: '0.660000', paragraph: 'p0-0' },
{ duration: '0.150000', name: 'the', time: '1.020000', paragraph: 'p0-0' },
{ duration: '0.380000', name: 'rat', time: '1.170000', paragraph: 'p0-0' },
{ duration: '0.770000', name: '.', time: '1.550000', paragraph: 'p0-0' },
{ duration: '0.360000', name: 'Arthur', time: '89.820000', paragraph: 'p1-0' },
{ duration: '0.390000', name: 'stood', time: '90.180000', paragraph: 'p1-0' },
{ duration: '0.090000', name: 'and', time: '90.570000', paragraph: 'p1-0' }
];
function searchFor(toSearch) {
var results = [];
toSearch = trimString(toSearch); // trim it
for(var i=0; i<objects.length; i++) {
for(var key in objects[i]) {
if(objects[i][key].indexOf(toSearch)!=-1) {
if(!itemExists(results, objects[i])) results.push(objects[i]);
}
}
}
return results;
}
log(searchFor('Arthur'))
我得到结果:
[
{
duration: '0.360000',
name: 'Arthur',
time: '0.660000',
paragraph: 'p0-0'
},
{
duration: '0.360000',
name: 'Arthur',
time: '89.820000',
paragraph: 'p1-0'
}
]
但是我一直在想如何将它变成一个 ramda 函数并能够添加多个搜索项并仅显示 p0-0
的结果(如果我使用 Arthur the
非常感谢任何建议。
在接近函数式风格时,对我有帮助的是从最基本的要求开始慢慢构建完整的规范。要求尚不清楚,但您似乎想要 return 一个与名称匹配的对象,并可能扩展此功能,以便您可以传入一个名称数组并返回一个对象数组。
所以让我们从最基本的要求开始,即 return 一个基于名称是否与给定参数匹配的布尔值。为此,我们将使用函数 propEq
:
const nameEq = pred => R.propEq('name', pred)
// This is just a partially application of:
// const nameEq = pred => obj => R.propEq('name', pred)(obj)
所以现在要在列表中找到所有匹配的对象,我们使用函数 filter
它将 return 任何元素,对于提供的函数
计算结果为真
const nameInList = pred => R.filter(nameEq(pred))
// This is again a partial application of:
// const nameInList = pred => obj => R.filter(nameEq(pred))(obj)
然后可以用
调用
nameInList('Arthur')(objects)
哪个return
[
{
"duration": "0.360000",
"name": "Arthur",
"paragraph": "p0-0",
"time": "0.660000"
},
{
"duration": "0.360000",
"name": "Arthur",
"paragraph": "p1-0",
"time": "89.820000"
}
]
或者我们可以部分应用我们的函数
const findArthur = nameInList('Arthur')
然后传入我们的对象列表
findArthur(objects)
然后我们可以通过定义更进一步来反转参数:
const flipped = R.compose(R.curry, R.flip(R.uncurryN(2, nameInList)))
这将允许我们将函数部分应用到 objects
并通过传入字符串简单地查找名称。
我有以下代码:
const trimString = (s) => s.trim()
const compareObjects = (o1, o2) => equals(o1, o2)
const itemExists = (haystack, needle) => contains(haystack, needle)
const objects = [
{ duration: '0.360000', name: 'Arthur', time: '0.660000', paragraph: 'p0-0' },
{ duration: '0.150000', name: 'the', time: '1.020000', paragraph: 'p0-0' },
{ duration: '0.380000', name: 'rat', time: '1.170000', paragraph: 'p0-0' },
{ duration: '0.770000', name: '.', time: '1.550000', paragraph: 'p0-0' },
{ duration: '0.360000', name: 'Arthur', time: '89.820000', paragraph: 'p1-0' },
{ duration: '0.390000', name: 'stood', time: '90.180000', paragraph: 'p1-0' },
{ duration: '0.090000', name: 'and', time: '90.570000', paragraph: 'p1-0' }
];
function searchFor(toSearch) {
var results = [];
toSearch = trimString(toSearch); // trim it
for(var i=0; i<objects.length; i++) {
for(var key in objects[i]) {
if(objects[i][key].indexOf(toSearch)!=-1) {
if(!itemExists(results, objects[i])) results.push(objects[i]);
}
}
}
return results;
}
log(searchFor('Arthur'))
我得到结果:
[
{
duration: '0.360000',
name: 'Arthur',
time: '0.660000',
paragraph: 'p0-0'
},
{
duration: '0.360000',
name: 'Arthur',
time: '89.820000',
paragraph: 'p1-0'
}
]
但是我一直在想如何将它变成一个 ramda 函数并能够添加多个搜索项并仅显示 p0-0
的结果(如果我使用 Arthur the
非常感谢任何建议。
在接近函数式风格时,对我有帮助的是从最基本的要求开始慢慢构建完整的规范。要求尚不清楚,但您似乎想要 return 一个与名称匹配的对象,并可能扩展此功能,以便您可以传入一个名称数组并返回一个对象数组。
所以让我们从最基本的要求开始,即 return 一个基于名称是否与给定参数匹配的布尔值。为此,我们将使用函数 propEq
:
const nameEq = pred => R.propEq('name', pred)
// This is just a partially application of:
// const nameEq = pred => obj => R.propEq('name', pred)(obj)
所以现在要在列表中找到所有匹配的对象,我们使用函数 filter
它将 return 任何元素,对于提供的函数
const nameInList = pred => R.filter(nameEq(pred))
// This is again a partial application of:
// const nameInList = pred => obj => R.filter(nameEq(pred))(obj)
然后可以用
调用nameInList('Arthur')(objects)
哪个return
[
{
"duration": "0.360000",
"name": "Arthur",
"paragraph": "p0-0",
"time": "0.660000"
},
{
"duration": "0.360000",
"name": "Arthur",
"paragraph": "p1-0",
"time": "89.820000"
}
]
或者我们可以部分应用我们的函数
const findArthur = nameInList('Arthur')
然后传入我们的对象列表
findArthur(objects)
然后我们可以通过定义更进一步来反转参数:
const flipped = R.compose(R.curry, R.flip(R.uncurryN(2, nameInList)))
这将允许我们将函数部分应用到 objects
并通过传入字符串简单地查找名称。