在数组上执行函数列表
Executing a list of functions on an array
除了简单的 map
或两个之外,我正在掌握使用函数式编程。我有一种情况,我希望能够根据 objects 的特定字段从 objects 的数组中过滤一些元素。这是一个人为的例子,但这里是:
我有一个字段定义列表,我想根据它们的标题提取其中两个。
const toSearch = [
{ title: "name", description: "Their name" },
{ title: "age", description: "Their age" },
{ title: "gender", description: "Their gender" }
]
const fieldsToFind = ["name", "age"]
let filterObjects = R.map(R.objOf('title'), fieldsToFind)
let filterFuncs = R.map(R.whereEq(R.__), filterObjects)
let found = R.map(R.filter, filterFuncs)
console.log("Filter objects:", JSON.stringify(filterObjects))
console.log("Filter functions:", JSON.stringify(filterFuncs))
console.log("Found:", found[0](toSearch))
console.log("Found:", found[1](toSearch))
如果我 运行 这个,输出的最后一个是我正在寻找的 toSearch
的两个元素,但它并不完全整洁。我一直在尝试让另一个 map
工作来绕过手动执行 found
元素,但我也觉得即使到了那个点我也在走一条过于迂回的路线。
虽然这是一个人为的示例,但是否有更简洁的方法以函数式风格完成此操作?
您可以使用 .reduce
来完成您的任务。 MDN 对 reduce 函数有一个非常简短的解释
I have a situation where I want to be able to filter some elements
from an array of objects, based on a particular field of those
objects.
对于你的情况,很简单
var filteredItems = toSearch.filter(function(value){ return fieldsToFind.indexOf(value.title) != -1 });
一个相当简单的方法是:
R.filter(R.where({R.title: R.contains(R.__, ['name', 'age'])}))(toSearch);
//=> [
// {"description": "Their name", "title": "name"},
// {"description": "Their age", "title": "age"}
// ]
或者,等价地,
R.filter(R.where({title: R.flip(R.contains)(['name', 'age'])}))(toSearch);
一个优势,尤其是当您将相关函数从 R
导入到您的范围时,它与您的问题域的读取有多接近:
var myFunc = filter(where({title: contains(__, ['name', 'age'])}));
myFunc = filter where the title contains 'name' or 'age'.
您可以在 Ramda REPL.
上看到实际效果
除了简单的 map
或两个之外,我正在掌握使用函数式编程。我有一种情况,我希望能够根据 objects 的特定字段从 objects 的数组中过滤一些元素。这是一个人为的例子,但这里是:
我有一个字段定义列表,我想根据它们的标题提取其中两个。
const toSearch = [
{ title: "name", description: "Their name" },
{ title: "age", description: "Their age" },
{ title: "gender", description: "Their gender" }
]
const fieldsToFind = ["name", "age"]
let filterObjects = R.map(R.objOf('title'), fieldsToFind)
let filterFuncs = R.map(R.whereEq(R.__), filterObjects)
let found = R.map(R.filter, filterFuncs)
console.log("Filter objects:", JSON.stringify(filterObjects))
console.log("Filter functions:", JSON.stringify(filterFuncs))
console.log("Found:", found[0](toSearch))
console.log("Found:", found[1](toSearch))
如果我 运行 这个,输出的最后一个是我正在寻找的 toSearch
的两个元素,但它并不完全整洁。我一直在尝试让另一个 map
工作来绕过手动执行 found
元素,但我也觉得即使到了那个点我也在走一条过于迂回的路线。
虽然这是一个人为的示例,但是否有更简洁的方法以函数式风格完成此操作?
您可以使用 .reduce
来完成您的任务。 MDN 对 reduce 函数有一个非常简短的解释
I have a situation where I want to be able to filter some elements from an array of objects, based on a particular field of those objects.
对于你的情况,很简单
var filteredItems = toSearch.filter(function(value){ return fieldsToFind.indexOf(value.title) != -1 });
一个相当简单的方法是:
R.filter(R.where({R.title: R.contains(R.__, ['name', 'age'])}))(toSearch);
//=> [
// {"description": "Their name", "title": "name"},
// {"description": "Their age", "title": "age"}
// ]
或者,等价地,
R.filter(R.where({title: R.flip(R.contains)(['name', 'age'])}))(toSearch);
一个优势,尤其是当您将相关函数从 R
导入到您的范围时,它与您的问题域的读取有多接近:
var myFunc = filter(where({title: contains(__, ['name', 'age'])}));
myFunc = filter where the title contains 'name' or 'age'.
您可以在 Ramda REPL.
上看到实际效果