2013-05-11 2 views
2

Я создал простую функцию: он имеет массив как вход и идентификатор. Функция предполагает взять все элементы «до» данной идеи.Переписать цикл в функциональном стиле

function takeBefore(stars, id) { 
     var taken = []; 
     for(var i = 0, length = stars.length; i < length; i++) { 
      if (stars[i].itemId === id) { 
       break; 
      } 

      taken.push(stars[i]); 
     } 

     return taken; 
    } 

Код ниже выполняет эту работу, но в последнее время я стал немного придирчивым. Хотелось бы избавиться от for-loop и некоторого функционального стиля.

Можно ли использовать underscore или ES5 функции для выполнения той же работы?

ответ

1

Этот тип материала обычно называется takeWhile/dropWhile. Вы можете реализовать их с помощью булевой итератор every():

function takeWhile(array, predicate) { 
    var pos = -1; 
    var all = array.every(function(x, n) { 
     return (pos = n), predicate(x); 
    }) 
    return array.slice(0, pos + all); 
} 

function dropWhile(array, predicate) { 
    var pos = -1; 
    var all = array.every(function(x, n) { 
     return (pos = n), predicate(x); 
    }) 
    return array.slice(pos + all); 
} 


a = [1,2,3,4,5,6,7] 
b = takeWhile(a, function(x) { return x < 5 }) // 1,2,3,4 
b = dropWhile(a, function(x) { return x < 5 }) // 5,6,7 
+0

, который работает очень хорошо! вы могли бы plz expay 'every' .. Я думал, что он возвращает логическое значение, как он используется как pos + all? –

+0

@alexanderb: на самом деле это хак. При использовании с '+', логические переменные преобразуются в ints (true = 1, false = 0), и я использую это, чтобы сдвинуть позицию на единицу, если все элементы соответствуют предикату. – georg

0

Вы могли бы сделать что-то вроде этого:

x = [1,2,3,4,5]; 
x.slice(0, x.indexOf(3)); 

Результаты:

[1, 2] 
Смежные вопросы