转换函数(地图等)的 Ramda 无点问题
Ramda point-free problems with transform functions (map, etc)
我有这个功能,基本上是将请求参数和查询参数映射到一个SQL语句:
function selectSingleResult(params, { order, limit, offset, fields, runset_id, txOffset, txFactor }) {
const transformer = R.when(R.equals('values'), R.compose(knex.raw.bind(knex), applyConversion({ txOffset, txFactor })))
const newFields = R.map(transformer , fields);
knex('myTable').select(...newFields) // etc...
理想情况下,我希望能够在函数外定义 transformer
,这样函数就可以变成:
const mapFields = R.map(transformer);
function selectSingleResult(params, { order, limit, offset, fields, runset_id, txOffset, txFactor }) {
knex('myTable').select(...mapFields(fields)) // etc...
问题是 applyConversion
函数需要给 selectSingleResult
参数。
这是我将函数转换为 map
时遇到的一个常见问题。它们通常需要参数而不是被映射的值。在这种情况下,我怎样才能以无点或至少更可测试的风格编写,而不至于最终嵌套函数太多?
感觉好像您正在尝试在没有多大意义的代码中无意义。但是有一个相反的概念,即从第二个参数中解构一大组字段,这似乎不是必需的,所以这看起来很混乱。 (这实际上可能是必要的:也许您在主函数的其余部分中使用了 order
、limit
、offset
和 runset_id
。)
我认为您只需再引入一层调用就可以几乎完成您所要求的,就像这样:
const transformer = (query) =>
R .when (R .equals ('values'), field => knex .raw (applyConversion (query) (field)))
const mapFields = R.pipe (transformer, map)
const selectSingleResult = (params, query) => {
knex ('myTable') .select (... mapFields (query) (query .fields))
// etc...
}
我把第二个参数命名为你的main函数query
;这是一个猜测,如果这令人困惑,请将 query
的所有实例替换为 foo
或对您有意义的内容。
注意mapFields
也可以写成const mapFields = (query) => R.map (transformer (query))
,但上面的版本似乎更简单。另请注意,我简化了 transformer
一点。当你无法完全到达那里时,我根本看不出有任何理由去尝试无积分。并且尝试将无点代码与 knex .raw
之类的 OO 结构混合在一起似乎会使事情变得混乱。
如果我没看错代码,我们也可以这样重写transformer
:
const transformer = (query) => (field) =>
field == 'values' ? knex .raw (applyConversion (query) ('values')) : field
但我无法确定这是否是一种改进。
我有这个功能,基本上是将请求参数和查询参数映射到一个SQL语句:
function selectSingleResult(params, { order, limit, offset, fields, runset_id, txOffset, txFactor }) {
const transformer = R.when(R.equals('values'), R.compose(knex.raw.bind(knex), applyConversion({ txOffset, txFactor })))
const newFields = R.map(transformer , fields);
knex('myTable').select(...newFields) // etc...
理想情况下,我希望能够在函数外定义 transformer
,这样函数就可以变成:
const mapFields = R.map(transformer);
function selectSingleResult(params, { order, limit, offset, fields, runset_id, txOffset, txFactor }) {
knex('myTable').select(...mapFields(fields)) // etc...
问题是 applyConversion
函数需要给 selectSingleResult
参数。
这是我将函数转换为 map
时遇到的一个常见问题。它们通常需要参数而不是被映射的值。在这种情况下,我怎样才能以无点或至少更可测试的风格编写,而不至于最终嵌套函数太多?
感觉好像您正在尝试在没有多大意义的代码中无意义。但是有一个相反的概念,即从第二个参数中解构一大组字段,这似乎不是必需的,所以这看起来很混乱。 (这实际上可能是必要的:也许您在主函数的其余部分中使用了 order
、limit
、offset
和 runset_id
。)
我认为您只需再引入一层调用就可以几乎完成您所要求的,就像这样:
const transformer = (query) =>
R .when (R .equals ('values'), field => knex .raw (applyConversion (query) (field)))
const mapFields = R.pipe (transformer, map)
const selectSingleResult = (params, query) => {
knex ('myTable') .select (... mapFields (query) (query .fields))
// etc...
}
我把第二个参数命名为你的main函数query
;这是一个猜测,如果这令人困惑,请将 query
的所有实例替换为 foo
或对您有意义的内容。
注意mapFields
也可以写成const mapFields = (query) => R.map (transformer (query))
,但上面的版本似乎更简单。另请注意,我简化了 transformer
一点。当你无法完全到达那里时,我根本看不出有任何理由去尝试无积分。并且尝试将无点代码与 knex .raw
之类的 OO 结构混合在一起似乎会使事情变得混乱。
如果我没看错代码,我们也可以这样重写transformer
:
const transformer = (query) => (field) =>
field == 'values' ? knex .raw (applyConversion (query) ('values')) : field
但我无法确定这是否是一种改进。