Рейтинг@Mail.ru
загрузкаидет загрузка

Новые функции для работы с массивами в ECMAScript 5

Читаю новое издание Флэнагана, нашел несколько новых полезных функций по работе с массивами.

forEach()
map()
filter()
every() и some()
reduce() и reduceRight()
indexOf() и lastIndexOf()

forEach()


Последовательно проходим каждый элемент массива и каждый раз вызываем функцию, которая передаётся первым и единственным параметром. В свою очередь эта передаваемая функция принимает три параметра: значение текущего элемента, его индекс и ссылку на сам массив.

Простейший пример:
var ar = [1,2,3];
ar.forEach(
function(element, index, array){
console.log(element, index, array);
});

Вывод:
1 0 [1, 2, 3]
2 1 [1, 2, 3]
3 2 [1, 2, 3]

Подсчитываем сумму всех элементов:
var ar = [1,2,3];
var sum = 0;
ar.forEach(
function(value){
sum += value;
});
console.log(sum);

Вывод: 6

Увеличиваем каждый элемент массива на 1
var ar = [1,2,3];
ar.forEach(
function(value, index, array){
array[index] = value + 1;
});
console.log(ar);

Вывод: [2,3,4]

К сожалению, если нам понадобится преждевременно выйти из цикла, то break здесь не сработает и мы получим ошибку "unlabeled break must be inside loop or switch", то есть break только в циклах или switch, а forEach не является ни тем ни другим, а методом Array.

Предлагается такая конструкция через возбуждение исключения, если функция, которая передается в forEach() возбуждает исключение foreach.break, то выполнение прекращается.
var ar = [1,2,3];
function foreach(array, func){
try{
array.forEach(func);
} catch(e){
if(e == foreach.break) return;
else throw e;
}
}
foreach.break = new Error('StopIteration');
foreach(ar, function(value) {
console.log(value);
if(value == 2)
throw foreach.break;
});

Вывод: 1,2. До третьего элемента мы уже не дойдем.

map()


Порядок вызова аналогичен forEach, за исключением, что callback-функция должна возвратить значение. То есть мы проходимся по каждому элементу, наша функция проделывает некие операции и возвращает новое значение, но не для этого массива, а нового, старый массив не изменяется!

Если массив был с дырками, то есть индексы с разрывами (a[0], a[5], a[78]), то результирующий массив будет иметь точно такой же вид (b[0], b[5], b[78])

Массив, все элементы которого на 1 больше, чем у исходного
var arA = [1,2,3];
var arB = arA.map(function(value){ return value + 1;
});
console.log(arA);
console.log(arB);


Вывод:
[1,2,3] - исходный массив не изменился
[2,3,4] - новый массив, после вызова map()

filter()


Полезна для фильтрации элементов, callback-функция (та которую мы передаём в filter, forEach, map и т.д.) должна возвращать true или false. В первом случае текущий элемент помещается в новый массив, в лругом мы идем дальше по списку.

Как и в случае с map() мы получаем на выходе новый массив, старый не меняется.

Оставить элементы меньшие 5
var arA = [1,2,3,4,5,6,7,8,9];
var arB = arA.filter(function(value){ return value < 5 ? true : false;
});
console.log(arA);
console.log(arB);

Вывод:
[1,2,3,4,5,6,7,8,9] - исходный массив не изменился
[1,2,3,4] - новый массив, после вызова filter()

every() и some()


Эти два метода возвращают не массив, а true/false.

every() возвращает true тогда и только тогда, когда callback-функция вернула true после всех вызовов дял каждого элемента.
var ar = [1,2,3,4,5,6,7,8,9];
var result = ar.every(function(value){ return value < 10;
});
console.log(result);

Вывод: true - все элементы массива меньше 10.
var ar = [1,2,3,4,5,6,7,8,9];
var result = ar.every(function(value){ return value < 5;
});
console.log(result);

Вывод: false - не все элементы массива меньше 5.

some() же возвращает true если хотя бы один раз callback-функция вернула true.
var ar = [1,2,3,4,5,6,7,8,9];
var result = ar.some(function(value){ return value < 5;
});
console.log(result);

Вывод: true - есть хотя бы один элемент меньше 5.
var ar = [1,2,3,4,5,6,7,8,9];
var result = ar.some(function(value){ return value > 50;
});
console.log(result);

Вывод: false - ни одного элемента больше 50.

reduce() и reduceRight()


Два параметра: первый - callback-функция, второй - начальное значение переменной.

callback-функция принимает два значения: первое это результат предыдущей работы функции, второе - очередной элемент массива.

Продемонстрировать лучше на примере:
var ar = [4,3,2,1];
var result = ar.reduce(function(x, y){ return x + y;
}, 0);
console.log(result);

Изначально первый параметр x = 0.
Шаг 1: x = 0, y = ar[0] = 4; x + y = 4;
Шаг 2: x = 4, y = ar[1] = 3; x + y = 7;
Шаг 3: x = 7, y = ar[2] = 2; x + y = 9;
Шаг 2: x = 9, y = ar[1] = 1; x + y = 10;

reduceRight идет с конца массива.

indexOf() и lastIndexOf()


Возвращает индекс первого и последнего вхождения элемента в массив.
var ar = [4,3,2,1,4];
console.log(ar.indexOf(4));
console.log(ar.lastIndexOf(4));

Вывод: 0 и 4


Ooooops

Looks like Twitter's feed isn't working at the moment.