edit
This commit is contained in:
parent
e78e527866
commit
05a93ced80
212 changed files with 3213 additions and 3968 deletions
|
@ -1,16 +1,16 @@
|
|||
# Массивы: методы
|
||||
|
||||
В этой главе мы рассмотрим встроенные методы массивов JavaScript.
|
||||
|
||||
[cut]
|
||||
|
||||
## Метод split
|
||||
## Метод split
|
||||
|
||||
Ситуация из реальной жизни. Мы пишем сервис отсылки сообщений и посетитель вводит имена тех, кому его отправить: `Маша, Петя, Марина, Василий...`. Но нам-то гораздо удобнее работать с массивом имен, чем с одной строкой.
|
||||
Ситуация из реальной жизни. Мы пишем сервис отсылки сообщений и посетитель вводит имена тех, кому его отправить: `Маша, Петя, Марина, Василий...`. Но нам-то гораздо удобнее работать с массивом имен, чем с одной строкой.
|
||||
|
||||
К счастью, есть метод `split(s)`, который позволяет превратить строку в массив, разбив ее по разделителю `s`. В примере ниже таким разделителем является строка из запятой и пробела.
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var names = 'Маша, Петя, Марина, Василий';
|
||||
|
||||
var arr = names.split(', ');
|
||||
|
@ -20,36 +20,31 @@ for (var i = 0; i < arr.length; i++) {
|
|||
}
|
||||
```
|
||||
|
||||
[smart header="Второй аргумент `split`"]
|
||||
````smart header="Второй аргумент `split`"
|
||||
У метода `split` есть необязательный второй аргумент -- ограничение на количество элементов в массиве. Если их больше, чем указано -- остаток массива будет отброшен:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
alert( "a,b,c,d".split(',', *!*2*/!*) ); // a,b
|
||||
```
|
||||
````
|
||||
|
||||
[/smart]
|
||||
|
||||
[smart header="Разбивка по буквам"]
|
||||
````smart header="Разбивка по буквам"
|
||||
Вызов `split` с пустой строкой разобьёт по буквам:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var str = "тест";
|
||||
|
||||
alert( str.split('') ); // т,е,с,т
|
||||
```
|
||||
````
|
||||
|
||||
[/smart]
|
||||
|
||||
## Метод join
|
||||
## Метод join
|
||||
|
||||
Вызов `arr.join(str)` делает в точности противоположное `split`. Он берет массив и склеивает его в строку, используя `str` как разделитель.
|
||||
|
||||
Например:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = ['Маша', 'Петя', 'Марина', 'Василий'];
|
||||
|
||||
var str = arr.join(';');
|
||||
|
@ -57,26 +52,23 @@ var str = arr.join(';');
|
|||
alert( str ); // Маша;Петя;Марина;Василий
|
||||
```
|
||||
|
||||
[smart header="new Array + join = Повторение строки"]
|
||||
````smart header="new Array + join = Повторение строки"
|
||||
Код для повторения строки `3` раза:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
alert( new Array(4).join("ля") ); // ляляля
|
||||
```
|
||||
|
||||
Как видно, `new Array(4)` делает массив без элементов длины 4, который `join` объединяет в строку, вставляя *между его элементами* строку `"ля"`.
|
||||
Как видно, `new Array(4)` делает массив без элементов длины 4, который `join` объединяет в строку, вставляя *между его элементами* строку `"ля"`.
|
||||
|
||||
В результате, так как элементы пусты, получается повторение строки. Такой вот небольшой трюк.
|
||||
[/smart]
|
||||
|
||||
````
|
||||
|
||||
## Удаление из массива
|
||||
|
||||
Так как массивы являются объектами, то для удаления ключа можно воспользоваться обычным `delete`:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = ["Я", "иду", "домой"];
|
||||
|
||||
delete arr[1]; // значение с индексом 1 удалено
|
||||
|
@ -91,23 +83,20 @@ alert( arr[1] ); // undefined
|
|||
|
||||
Поэтому для удаления используются специальные методы: из начала -- `shift`, с конца -- `pop`, а из середины -- `splice`, с которым мы сейчас познакомимся.
|
||||
|
||||
## Метод splice
|
||||
## Метод splice
|
||||
|
||||
Метод `splice` -- это универсальный раскладной нож для работы с массивами. Умеет все: удалять элементы, вставлять элементы, заменять элементы -- по очереди и одновременно.
|
||||
|
||||
Его синтаксис:
|
||||
|
||||
<dl>
|
||||
<dt>`arr.splice(index[, deleteCount, elem1, ..., elemN])`</dt>
|
||||
<dd>Удалить `deleteCount` элементов, начиная с номера `index`, а затем вставить `elem1, ..., elemN` на их место. Возвращает массив из удалённых элементов.</dd>
|
||||
</dl>
|
||||
`arr.splice(index[, deleteCount, elem1, ..., elemN])`
|
||||
: Удалить `deleteCount` элементов, начиная с номера `index`, а затем вставить `elem1, ..., elemN` на их место. Возвращает массив из удалённых элементов.
|
||||
|
||||
Этот метод проще всего понять, рассмотрев примеры.
|
||||
|
||||
Начнём с удаления:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = ["Я", "изучаю", "JavaScript"];
|
||||
|
||||
*!*
|
||||
|
@ -119,36 +108,33 @@ alert( arr ); // осталось ["Я", "JavaScript"]
|
|||
|
||||
В следующем примере мы удалим 3 элемента и вставим другие на их место:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = [*!*"Я", "сейчас", "изучаю",*/!* "JavaScript"];
|
||||
|
||||
// удалить 3 первых элемента и добавить другие вместо них
|
||||
arr.splice(0, 3, "Мы", "изучаем")
|
||||
arr.splice(0, 3, "Мы", "изучаем")
|
||||
|
||||
alert( arr ) // теперь [*!*"Мы", "изучаем"*/!*, "JavaScript"]
|
||||
```
|
||||
|
||||
Здесь видно, что `splice` возвращает массив из удаленных элементов:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = [*!*"Я", "сейчас",*/!* "изучаю", "JavaScript"];
|
||||
|
||||
// удалить 2 первых элемента
|
||||
var removed = arr.splice(0, 2);
|
||||
// удалить 2 первых элемента
|
||||
var removed = arr.splice(0, 2);
|
||||
|
||||
alert( removed ); // "Я", "сейчас" <-- array of removed elements
|
||||
```
|
||||
|
||||
Метод `splice` также может вставлять элементы без удаления, для этого достаточно установить `deleteCount` в `0`:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = ["Я", "изучаю", "JavaScript"];
|
||||
|
||||
// с позиции 2
|
||||
// удалить 0
|
||||
// с позиции 2
|
||||
// удалить 0
|
||||
// вставить "сложный", "язык"
|
||||
arr.splice(2, 0, "сложный", "язык");
|
||||
|
||||
|
@ -157,26 +143,24 @@ alert( arr ); // "Я", "изучаю", "сложный", "язык", "JavaScript
|
|||
|
||||
Допускается использование отрицательного номера позиции, которая в этом случае отсчитывается с конца:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = [1, 2, 5]
|
||||
|
||||
// начиная с позиции индексом -1 (предпоследний элемент)
|
||||
// удалить 0 элементов,
|
||||
// удалить 0 элементов,
|
||||
// затем вставить числа 3 и 4
|
||||
arr.splice(-1, 0, 3, 4);
|
||||
|
||||
alert( arr ); // результат: 1,2,3,4,5
|
||||
```
|
||||
|
||||
## Метод slice
|
||||
## Метод slice
|
||||
|
||||
Метод `slice(begin, end)` копирует участок массива от `begin` до `end`, не включая `end`. Исходный массив при этом не меняется.
|
||||
|
||||
Например:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = ["Почему", "надо", "учить", "JavaScript"];
|
||||
|
||||
var arr2 = arr.slice(1, 3); // элементы 1, 2 (не включая 3)
|
||||
|
@ -185,43 +169,34 @@ alert( arr2 ); // надо, учить
|
|||
```
|
||||
|
||||
Аргументы ведут себя так же, как и в строковом `slice`:
|
||||
<ul>
|
||||
<li>Если не указать `end` -- копирование будет до конца массива:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
var arr = ["Почему", "надо", "учить", "JavaScript"];
|
||||
- Если не указать `end` -- копирование будет до конца массива:
|
||||
|
||||
alert( arr.slice(1) ); // взять все элементы, начиная с номера 1
|
||||
```
|
||||
```js run
|
||||
var arr = ["Почему", "надо", "учить", "JavaScript"];
|
||||
|
||||
</li>
|
||||
<li>Можно использовать отрицательные индексы, они отсчитываются с конца:
|
||||
alert( arr.slice(1) ); // взять все элементы, начиная с номера 1
|
||||
```
|
||||
- Можно использовать отрицательные индексы, они отсчитываются с конца:
|
||||
|
||||
```js
|
||||
var arr2 = arr.slice(-2); // копировать от 2го элемента с конца и дальше
|
||||
```
|
||||
```js
|
||||
var arr2 = arr.slice(-2); // копировать от 2го элемента с конца и дальше
|
||||
```
|
||||
- Если вообще не указать аргументов -- скопируется весь массив:
|
||||
|
||||
</li>
|
||||
<li>Если вообще не указать аргументов -- скопируется весь массив:
|
||||
```js
|
||||
var fullCopy = arr.slice();
|
||||
```
|
||||
|
||||
```js
|
||||
var fullCopy = arr.slice();
|
||||
```
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
[smart header="Совсем как в строках"]
|
||||
```smart header="Совсем как в строках"
|
||||
Синтаксис метода `slice` одинаков для строк и для массивов. Тем проще его запомнить.
|
||||
[/smart]
|
||||
```
|
||||
|
||||
## Сортировка, метод sort(fn)
|
||||
## Сортировка, метод sort(fn)
|
||||
|
||||
Метод `sort()` сортирует массив *на месте*. Например:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = [ 1, 2, 15 ];
|
||||
|
||||
arr.sort();
|
||||
|
@ -229,9 +204,9 @@ arr.sort();
|
|||
alert( arr ); // *!*1, 15, 2*/!*
|
||||
```
|
||||
|
||||
Не заметили ничего странного в этом примере?
|
||||
Не заметили ничего странного в этом примере?
|
||||
|
||||
Порядок стал `1, 15, 2`, это точно не сортировка чисел. Почему?
|
||||
Порядок стал `1, 15, 2`, это точно не сортировка чисел. Почему?
|
||||
|
||||
**Это произошло потому, что по умолчанию `sort` сортирует, преобразуя элементы к строке.**
|
||||
|
||||
|
@ -247,8 +222,7 @@ alert( arr ); // *!*1, 15, 2*/!*
|
|||
|
||||
Например, укажем эту функцию явно, отсортируем элементы массива как числа:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
function compareNumeric(a, b) {
|
||||
if (a > b) return 1;
|
||||
if (a < b) return -1;
|
||||
|
@ -273,30 +247,25 @@ arr.sort( compareNumeric*!*()*/!* ); // не сработает
|
|||
|
||||
Алгоритм сортировки, встроенный в JavaScript, будет передавать ей для сравнения элементы массива. Она должна возвращать:
|
||||
|
||||
<ul>
|
||||
<li>Положительное значение, если `a > b`,</li>
|
||||
<li>Отрицательное значение, если `a < b`,</li>
|
||||
<li>Если равны -- можно `0`, но вообще -- не важно, что возвращать, их взаимный порядок не имеет значения.</li>
|
||||
</ul>
|
||||
- Положительное значение, если `a > b`,
|
||||
- Отрицательное значение, если `a < b`,
|
||||
- Если равны -- можно `0`, но вообще -- не важно, что возвращать, их взаимный порядок не имеет значения.
|
||||
|
||||
|
||||
[smart header="Алгоритм сортировки"]
|
||||
````smart header="Алгоритм сортировки"
|
||||
В методе `sort`, внутри самого интерпретатора JavaScript, реализован универсальный алгоритм сортировки. Как правило, это ["\"быстрая сортировка\""](http://algolist.manual.ru/sort/quick_sort.php), дополнительно оптимизированная для небольших массивов.
|
||||
|
||||
Он решает, какие пары элементов и когда сравнивать, чтобы отсортировать побыстрее. Мы даём ему функцию -- способ сравнения, дальше он вызывает её сам.
|
||||
|
||||
Кстати, те значения, с которыми `sort` вызывает функцию сравнения, можно увидеть, если вставить в неё `alert`:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
[1, -2, 15, 2, 0, 8].sort(function(a, b) {
|
||||
alert( a + " <> " + b );
|
||||
});
|
||||
```
|
||||
````
|
||||
|
||||
[/smart]
|
||||
|
||||
[smart header="Сравнение `compareNumeric` в одну строку"]
|
||||
````smart header="Сравнение `compareNumeric` в одну строку"
|
||||
Функцию `compareNumeric` для сравнения элементов-чисел можно упростить до одной строчки.
|
||||
|
||||
```js
|
||||
|
@ -305,16 +274,14 @@ function compareNumeric(a, b) {
|
|||
}
|
||||
```
|
||||
|
||||
Эта функция вполне подходит для `sort`, так как возвращает положительное число, если `a > b`, отрицательное, если наоборот, и `0`, если числа равны.
|
||||
[/smart]
|
||||
|
||||
Эта функция вполне подходит для `sort`, так как возвращает положительное число, если `a > b`, отрицательное, если наоборот, и `0`, если числа равны.
|
||||
````
|
||||
|
||||
## reverse
|
||||
|
||||
Метод [arr.reverse()](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reverse) меняет порядок элементов в массиве на обратный.
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = [1, 2, 3];
|
||||
arr.reverse();
|
||||
|
||||
|
@ -327,8 +294,7 @@ alert( arr ); // 3,2,1
|
|||
|
||||
Например:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = [1, 2];
|
||||
*!*
|
||||
var newArr = arr.concat(3, 4);
|
||||
|
@ -343,8 +309,7 @@ alert( newArr ); // 1,2,3,4
|
|||
|
||||
Например:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = [1, 2];
|
||||
|
||||
*!*
|
||||
|
@ -358,17 +323,15 @@ alert( newArr ); // 1,2,3,4,5
|
|||
|
||||
Эти методы не поддерживаются в IE8-. Для их поддержки подключите библиотеку [ES5-shim](https://github.com/kriskowal/es5-shim).
|
||||
|
||||
|
||||
Метод ["arr.indexOf(searchElement[, fromIndex])"](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf) возвращает номер элемента `searchElement` в массиве `arr` или `-1`, если его нет.
|
||||
Метод ["arr.indexOf(searchElement[, fromIndex])"](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf) возвращает номер элемента `searchElement` в массиве `arr` или `-1`, если его нет.
|
||||
|
||||
Поиск начинается с номера `fromIndex`, если он указан. Если нет -- с начала массива.
|
||||
|
||||
**Для поиска используется строгое сравнение `===`.**
|
||||
**Для поиска используется строгое сравнение `===`.**
|
||||
|
||||
Например:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var arr = [1, 0, false];
|
||||
|
||||
alert( arr.indexOf(0) ); // 1
|
||||
|
@ -378,13 +341,13 @@ alert( arr.indexOf(null) ); // -1
|
|||
|
||||
Как вы могли заметить, по синтаксису он полностью аналогичен методу [indexOf для строк](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/indexOf).
|
||||
|
||||
Метод ["arr.lastIndexOf(searchElement[, fromIndex])"](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf) ищет справа-налево: с конца массива или с номера `fromIndex`, если он указан.
|
||||
Метод ["arr.lastIndexOf(searchElement[, fromIndex])"](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf) ищет справа-налево: с конца массива или с номера `fromIndex`, если он указан.
|
||||
|
||||
[warn header="Методы `indexOf/lastIndexOf` осуществляют поиск перебором"]
|
||||
```warn header="Методы `indexOf/lastIndexOf` осуществляют поиск перебором"
|
||||
Если нужно проверить, существует ли значение в массиве -- его нужно перебрать. Только так. Внутренняя реализация `indexOf/lastIndexOf` осуществляет полный перебор, аналогичный циклу `for` по массиву. Чем длиннее массив, тем дольше он будет работать.
|
||||
[/warn]
|
||||
```
|
||||
|
||||
[smart header="Коллекция уникальных элементов"]
|
||||
````smart header="Коллекция уникальных элементов"
|
||||
Рассмотрим задачу -- есть коллекция строк, и нужно быстро проверять: есть ли в ней какой-то элемент. Массив для этого не подходит из-за медленного `indexOf`. Но подходит объект! Доступ к свойству объекта осуществляется очень быстро, так что можно сделать все элементы ключами объекта и проверять, есть ли уже такой ключ.
|
||||
|
||||
Например, организуем такую проверку для коллекции строк `"div"`, `"a"` и `"form"`:
|
||||
|
@ -400,13 +363,10 @@ for (var i = 0; i < items.length; i++) {
|
|||
}
|
||||
```
|
||||
|
||||
Теперь для проверки, есть ли ключ `key`, достаточно выполнить `if (store[key])`. Если есть -- можно использовать значение, если нет -- добавить.
|
||||
Теперь для проверки, есть ли ключ `key`, достаточно выполнить `if (store[key])`. Если есть -- можно использовать значение, если нет -- добавить.
|
||||
|
||||
Такое решение работает только со строками, но применимо к любым элементам, для которых можно вычислить строковый "уникальный ключ".
|
||||
[/smart]
|
||||
|
||||
|
||||
|
||||
````
|
||||
|
||||
## Object.keys(obj)
|
||||
|
||||
|
@ -414,8 +374,7 @@ for (var i = 0; i < items.length; i++) {
|
|||
|
||||
Если мы хотим работать с ними в виде массива, то к нашим услугам -- замечательный метод [Object.keys(obj)](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys). Он поддерживается везде, кроме IE8-:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
```js run
|
||||
var user = {
|
||||
name: "Петя",
|
||||
age: 30
|
||||
|
@ -429,13 +388,12 @@ alert( keys ); // name, age
|
|||
## Итого
|
||||
|
||||
Методы:
|
||||
<ul>
|
||||
<li>`push/pop`, `shift/unshift`, `splice` -- для добавления и удаления элементов.</li>
|
||||
<li>`join/split` -- для преобразования строки в массив и обратно.</li>
|
||||
<li>`sort` -- для сортировки массива. Если не передать функцию сравнения -- сортирует элементы как строки.</li>
|
||||
<li>`reverse` -- меняет порядок элементов на обратный.</li>
|
||||
<li>`concat` -- объединяет массивы.</li>
|
||||
<li>`indexOf/lastIndexOf` -- возвращают позицию элемента в массиве (не поддерживается в IE8-).</li>
|
||||
</ul>
|
||||
|
||||
|
||||
- `push/pop`, `shift/unshift`, `splice` -- для добавления и удаления элементов.
|
||||
- `join/split` -- для преобразования строки в массив и обратно.
|
||||
- `sort` -- для сортировки массива. Если не передать функцию сравнения -- сортирует элементы как строки.
|
||||
- `reverse` -- меняет порядок элементов на обратный.
|
||||
- `concat` -- объединяет массивы.
|
||||
- `indexOf/lastIndexOf` -- возвращают позицию элемента в массиве (не поддерживается в IE8-).
|
||||
|
||||
Изученных нами методов достаточно в 95% случаях, но существуют и другие. Для знакомства с ними рекомендуется заглянуть в справочник <a href="http://javascript.ru/Array">Array</a> и [Array в Mozilla Developer Network](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array).
|
Loading…
Add table
Add a link
Reference in a new issue