繁体   English   中英

Ramda:拒绝谓词数组

[英]Ramda: Rejects from predicate array

https://jsbin.com/ziyufuxacu/edit?html,js,console,output

如何报告谓词数组的拒绝和仅第一个拒绝

这是我的尝试,但我觉得有 ramda 函数可以使这更通用,例如,如果我有 10 个谓词

var selected = [{
  Label: "a",
  Invalid: false,
  Deleted: true
}, {
  Label: "b",
  Invalid: false,
  Deleted: false
}, {
  Label: "c",
  Invalid: true,
  Deleted: false
}];


var canEditPredicates = [
  R.propEq("Deleted", false),
  R.propEq("Invalid", false),
  R.propEq("Label", "c")
];




var deleted = R.reject(canEditPredicates[0], selected);
var invalid = R.reject(canEditPredicates[1], R.without(deleted, selected));
var names = R.reject(canEditPredicates[2], R.without(deleted, R.without(invalid, selected)));

var rv = "The following items are bad:";



if (deleted.length) {
  rv += "\r\nDeleted items: " + R.join(", ")(R.pluck("Label")(deleted));
}

if (invalid.length) {
  rv += "\r\ninvalid items: " + R.join(", ")(R.pluck("Label")(invalid));
}
if (names.length) {
  rv += "\r\nnames items: " + R.join(", ")(R.pluck("Label")(names));
}


console.log(rv);

输出

The following items are bad:
Deleted items: a
invalid items: c
names items: b

要了解项目被拒绝的原因(谓词的索引),您可以使用带有谓词数组的翻转 R.findIndex。 谓词应该被补充,因为我们想要一个失败的答案为true 传递给 fins 的值应该用 R.applyTo 包裹,因为 R.find 需要一个谓词函数。

然后您可以映射项目数组,传递值,并获取每个失败项目的谓词索引。 如果该项目通过了所有检查(补充失败),您将获得-1而不是谓词索引。

 const { propEq, map, pipe, applyTo, flip, findIndex, complement } = R; const canEditPredicates = [ propEq("Deleted", false), propEq("Invalid", false), propEq("Label", "c") ]; const findFailedPredicateIndex = pipe(applyTo, flip(findIndex)(map(complement, canEditPredicates))); const findFailed = map(findFailedPredicateIndex); const selected = [{"Label":"a","Invalid":false,"Deleted":true},{"Label":"b","Invalid":false,"Deleted":false},{"Label":"c","Invalid":true,"Deleted":false},{"Label":"c","Invalid":false,"Deleted":false}]; const result = findFailed(selected); console.log(result);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>

此版本对您的输入具有多种自由。 他们可能没有道理。 但在我看来,它们是为了形成一个更合乎逻辑的系统。 如果更改太过分,请随意忽略。

这样做的最大作用是颠倒谓词的含义。 这些版本现在列为cannotEditPredicates而不是canEditPredicates 这使我们可以更简单地编写它们。 例如, Deleted谓词可以只是R.prop("Deleted")而不是R.prop('Deleted', false)

我还以不同的方式将它们捆绑在一起,以便我们更清晰地捕获失败结果。 它们不是数组,而是收集在以您在预期输出中使用的名称为键的对象中。

这给了我们一个输出结构,如

{
  Deleted: ["a", "e"],
  invalid: ["c"],
  name: ["b"]
}

但是我们可以简单地更改它以包含整个对象而不是标签。

这是它的样子:

 const rejectPreds = (selected, cannotEditPredicates) => R.reduce ( (output, item) => { const rec = R.find (([k, v]) => v (item))(R.toPairs (cannotEditPredicates)) return rec == undefined ? output : {...output, [rec [0]]: [...output [rec [0]], item .Label]} }, R.map (v => []) (cannotEditPredicates), selected ) const selected = [ {Label: "a", Invalid: false, Deleted: true}, {Label: "b", Invalid: false, Deleted: false}, {Label: "c", Invalid: true, Deleted: false}, {Label: "d", Invalid: false, Deleted: false}, {Label: "e", Invalid: false, Deleted: true} ]; const cannotEditPredicates = { Deleted: R.prop("Deleted"), invalid: R.prop("Invalid"), name: R.propEq("Label", "b") } const rejected = rejectPreds (selected, cannotEditPredicates) console .log (rejected) console .log (`The following items are bad: ${Object .entries (rejected) .map (([n, v]) => `${n}: [${[...v]}]`) .join ('\\n')} `)
 .as-console-wrapper {max-height: 100% !important; top: 0}
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>

请注意,尽管这使用了各种 Ramda 函数,但几乎所有函数都可以轻松地替换为Array.prototype上的版本。 唯一更困难的地方是map调用,Ramda 以相当明显的方式在对象上运行。 如果需要,使用Object.entriesArray.prototype.mapObject.fromEntries的舞蹈在普通 JS 中编写mapObject函数会很容易。

我现在没有时间来玩这个,但我认为在这里使用“ Either或“ Result实现可能值得研究。 这可能会导致更多的逻辑代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM