2015-03-02 4 views
2

On Lucee 4.5.1.003 У меня есть эта функция, где LineArray - это массив объектов LineItem.Lucee array.each возвращаемое значение

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?

Редактировать: Чтобы быть ясным, вторая функция возвращает найденный объект.

ответ

2

Вы должны выглядеть немного ближе на код в первом примере:

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() "возвращает 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; 
} 

One использует some(), когда один хочет перебрать массив только до тех пор некоторые критерии не сопоставляется. Здесь я использую это, чтобы установить matchedElement, когда выполняются критерии выхода.

+0

Не встретишь «некоторые» раньше. Есть ли какая-либо польза от использования закрытия в этом случае над простым циклом for-in? Это уменьшит вдвое. строк и читайте более четко: 'for (var item в this.LineArray) { if (item.id == id) return item; } ' – CfSimplicity

+0

Использование метода итератора, специально предназначенного для вида работы под рукой, более яснее в намерениях, чем просто использование общего цикла. –

0

Если идентификатор всегда ожидается существовать использование:

public function getLineItemDetailsById(required numeric id){ 
    return this.LineArray.Find(function(i){return i.ID==id);}); 
} 
0
.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 

Хотя лучший способ в большинстве случаев, является заполнение этого .lineStruct из этого.lineArray, раньше времени.

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