在链条上使用后链

Lodash using rearg in chain

本文关键字:      更新时间:2023-09-26

我试过使用rearg有和没有链接,我只得到错误时使用链接。我已经阅读了文档,看起来rearg应该很好地发挥链,因为它返回一个链包装方法。但是,我得到以下错误:

Error: _.chain(...).keys(...).myFunc is not a function

的代码:

var myList = ['a','b','c','d']
var myJSON = {
  'a':1,
  'b':2
};
var myFunc = _.rearg(_.difference, [1, 0]); //switching order of arguments
var hasAllKeys = _.chain(myJSON)
                  .keys()
                  .myFunc(myList)
                  .value();

当然这段代码工作得很好(尽管输出不是我需要的):

var wrong = _.chain(myJSON)
             .keys()
             .difference(myList)
             .values();

我知道这个问题很老了,但它是Lodash中关于链接的罕见问题之一,没有得到回答,试图回答它可以让我在文档中深入挖掘并理解这个库…这是一个很好的机会,尝试"运行JS代码"的特性堆栈溢出…

我终于明白它不能像你那样工作。

首先,rearg真的是可链的吗?答案是:是的。我尝试了下面的代码:

var last = _(twoParams).ary(1).rearg([1, 0]).value();

,实际上,当我用两个参数调用last时,它只使用最后一个参数调用twoParams

当然,rearg只能与提供函数作为输出,期望函数作为输入的函数链接,即。只能在函数链中处理函数

现在,你的代码不能工作,因为如果rearg是可链的,它的输出不是!它的输出是一个普通的老式JavaScript函数,这些函数是不可链接的。好消息是Lodash非常聪明,它提供了一种使函数可链化的方法。您必须使用mixin,默认情况下,它将提供的函数添加到Lodash并使其可链接。例如,参见在lodash中使用自定义函数创建链,其中解释了如何做到这一点。与这些示例不同,我将遵循Lodash文档的建议,并使用runInContext来避免使用应该保留在本地的新函数污染Lodash。

这是我的实验。我冒昧地重命名了一些标识符,因为我讨厌myXxx名称,更喜欢更具描述性的名称…

// Generic code to display resuts
var results = document.getElementById('pls-results');
function showHTML(html)
{
  results.insertAdjacentHTML('beforeend', html);
}
function show(text)
{
  showHTML("<p>" + text + "<p>");
}
function showObject(obj)
{
  show("<p>" + JSON.stringify(obj) + "<p>");
}
// The real code
var keyList = [ 'a', 'b', 'c', 'd' ];
var incompleteJson = { "a": 1, "b": 2 };
var fullJson = { "a": 1, "b": 2, "c": true, "d": "yes" };
// A simple way to do what is implied by the variable name
showHTML("<h3>Has All Keys</h3>");
show("Incomplete Json");
var diff = _.difference(keyList, _.keys(incompleteJson));
var hasAllKeys = diff.length === 0;
show(hasAllKeys);
show("Full Json");
diff = _.difference(keyList, _.keys(fullJson));
hasAllKeys = diff.length === 0;
show(hasAllKeys);
// What you try to do
showHTML("<h3>Consume Expected Keys</h3>");
var localLodash = _.runInContext();
localLodash.mixin(
    {
        'reverseDiff': _.rearg(_.difference, [1, 0])  // switching order of arguments
    }
);
show("Incomplete Json");
var expectedKeys = localLodash.chain(incompleteJson)
     .keys()
     .reverseDiff(keyList)
     .value();
showObject(expectedKeys);
show("Full Json");
expectedKeys = localLodash.chain(fullJson)
     .keys()
     .reverseDiff(keyList)
     .value();
showObject(expectedKeys);
<div id="pls-results"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>

这个答案扩展了PhiLho的出色答案。希望这将有助于未来的读者对问题和解决方案有更多的了解。在下面的代码片段中,您可以看到与PhiLho的代码片段和其他2个测试中相同的结果:

  1. 链接_.difference而不是_.reverseDiff :当对象在keyList中没有找到一些键时返回结果(而不是在keyList中没有找到键)。
  2. 直接的替代方案( _.difference(myList, _.keys(myJSON)) ):用更少的代码返回预期的输出(这个问题的意图可能不是关于这个解决方案,但是通过显示这个替代方案,您可能更容易理解问题)。

// Generic code to display resuts
var results = document.getElementById('pls-results');
function showHTML(html) {
  results.insertAdjacentHTML('beforeend', html);
}
// Set up test data
var keyList = [ 'a', 'b', 'c', 'd' ];
var incompleteJson = { "a": 1, "b": 2 };
var fullJson = { "a": 1, "b": 2, "c": true, "d": "yes" };
var extraPropertyJson = { "a": 1, "b": 2, "c": true, "d": "yes", 'z': 26 };
// Set up test helper methods
var renderLine = function(label, obj) {
  return "<tr><td>" + label + "</td><td>" + JSON.stringify(obj) + "</td></tr>";
};
var test = function(funcName, funcToTest) {
  var html = "<h3>" + funcName + "</h3><table>";
  html += renderLine("Incomplete Json", funcToTest(incompleteJson));
  html += renderLine("Full Json", funcToTest(fullJson));
  html += renderLine("Extra Property Json", funcToTest(extraPropertyJson));
  html += "</table>";
  showHTML(html);
};
// The real code
var local_ = _.runInContext();
local_.mixin({
  'reverseDiff': _.rearg(_.difference, [1, 0])  // switching order of arguments
});
// Tests execution
test("_.difference",                        function(json) { return      _.chain(json).keys(). difference(keyList).value(); });
test("local_.reverseDiff",                  function(json) { return local_.chain(json).keys().reverseDiff(keyList).value(); });
test("_.difference(keyList, _.keys(json))", function(json) { return _.difference(keyList, _.keys(json)); });
<div id="pls-results"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>

相关文章:
  • 没有找到相关文章