【问题标题】:Lucee array.each return valueLucee array.each 返回值
【发布时间】:2016-07-21 22:00:49
【问题描述】:

在 Lucee 4.5.1.003 我有这个函数,其中 LineArray 是 LineItem 对象的数组。

public function getLineItemDetailsById(required numeric id){
    this.LineArray.each(function(i){
        if(i.Id == id){
            return i;
        }
    });
}

即使存在匹配,该函数也会返回 null。如果我添加一个 var 来保存找到的对象,则返回该 var。

public function getLineItemDetailsById(required numeric id){
    var found = '';
    this.LineArray.each(function(i){
        if(i.Id == id){
            found = i;
            //return i;
        }
    });
    return found;
}

我是在期望 array.each 返回 i 时做错了什么,还是我误解了 array.each 的工作原理?

编辑:要清楚,第二个函数确实返回找到的对象。

【问题讨论】:

    标签: cfml lucee


    【解决方案1】:

    您需要仔细查看第一个示例中的代码:

    public function getLineItemDetailsById(required numeric id){ // first function
        this.LineArray.each(function(i){ // second function
            if(i.Id == id){
                return i; // return for second function
            }
        });
        // no return from first function
    }
    

    我已经稍微注释了它以证明您的问题。 getLineItemDetailsById() "returns null" 因为你根本没有从中返回任何东西。所以如果你有:

    result = getLineItemDetailsById(1);
    

    那么getLineItemDetailsById() 没有返回任何东西,所以result 最终成为null

    这就是你看到的问题。

    此外,您不希望在该函数中使用each():只有当您确定要遍历整个数组时才会使用each()。在您的情况下,您似乎想在找到 id 的匹配项后立即退出。

    在这种情况下,你想要这样的东西:

    public function getLineItemDetailsById(required numeric id){
        var matchedElement = null; 
        this.LineArray.some(function(element){
            if(element.Id == id){
                matchedElement = element;
                return true;
            }
        });
        return matchedElement;
    }
    

    当一个人想要迭代一个数组直到某些条件匹配时,一个人使用some()。在这里,我利用它在满足退出条件时设置matchedElement

    【讨论】:

    • 之前没遇到过some。在这种情况下,通过简单的for-in 循环使用闭包有什么好处吗?那将使否减半。行数,阅读更清楚:for( var item in this.LineArray ){ if( item.id == id ) return item; }
    • 使用专门针对手头工作的迭代器方法比仅使用通用循环更清晰。
    【解决方案2】:

    如果 ID 始终存在,请使用:

    public function getLineItemDetailsById(required numeric id){
        return this.LineArray.Find(function(i){return i.ID==id);});
    }
    

    【讨论】:

      【解决方案3】:
      .each     loops through the entire array and returns void
      .reduce   returns a single value after looping through all elements
      .some     allows an exit sooner than each
      

      (查看文档了解更多方法)

      for(i in this.lineArray)if(i.id is id) return i; ... avoids some overhead
      

      虽然在大多数情况下更好的方法是提前从 this.lineArray 填充 this.lineStruct。

      this.lineStruct={}; 
      this.lineArray.each(function(i){this.lineStruct[i.id]=i;});
      function getLineById(id) 
      {   return this.lineStruct.keyexists(id)?this.lineStruct[id]:null;   }
      

      【讨论】:

        猜你喜欢
        • 2014-12-05
        • 2017-01-28
        • 2016-03-22
        • 2017-01-10
        • 1970-01-01
        • 1970-01-01
        • 2011-02-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多