Home

Arrays — Part 1st (Arrays and array processing)

Содержание

1. Вступление

Массив – это упорядоченная коллекция значений. Значения в массиве называются элементами, и каждый элемент характеризуется числовой позицией (или строкой если речь идет о ассоциативных массивах) в массиве, которая называется индексом (ключ для ассоциативных). Массивы в языке JavaScript являются нети­пизированными: элементы массива могут иметь любой тип, причем разные элементы одного и того же массива могут иметь разные типы. Элементы массива могут даже быть объектами или другими массивами, что позволяет создавать сложные структуры данных, такие как массивы объектов и массивы массивов.

В JavaScript есть 2 типа массивов: ассоциативные массивы и массивы с числовыми индексами.

Ассоциативные массивы в JavaScript это не отдельный тип коллекции, а всего лишь объекты без методов. То есть если объект хранит данные и не делает с ними никаких действий это ассоциативный массив.

В отличии от ассоциативных массивов, массивы с числовыми индексами в JavaScript считаются отдельной кастой (говорят подкласом) обычных объектов. Но не образуют отдельного типа данных как в других языках програмирования.

2. Объекты как ассоциативные массивы

В этой главе мы рассмотрим использование объектов именно как массивов.

Ассоциативные массивы - структура данных, в которой можно хранить любые данные в формате ключ-значение.

Именно синтаксис доступа к полям объекта через квадратные скобки делает их похожими на ассоциативные массивы других языков програмирования.

Так как ассоциативные массивы это просто объекты, все методики работы с объектами справедливы и к ассоциативным массивам.

Могут закрасться сомнения нужно ли вводить такой термин как ассоциативные массивы, для JS колекций если это всего лишь объекты, но стоит знать что ассоциативные массивы имеют некие механизмы оптимизации, что приводит к отличиям реализаций таких структур на уровне памяти. А именно ассоциативные массивы поддерживают механизм компактного представления в памяти.

3. Массивы с числовыми индексами

В этой главе мы рассмотрим использование подкласса Array - что реализовывает массивы с числовыми индексами в JavaScript.

С этого момента и в будущем массивы с числовыми индексами мы будем называть просто массивами.

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

Отсчет индексов массивов в языке JavaScript начинается с нуля и для них используются 32-битные целые числа: первый элемент массива имеет индекс 0, а наибольший возможный индекс имеет значение 4294967295 элементов.

4. Создание массивов

Легче всего создать массив с помощью литерала, который представляет собой простой список разделенных запятыми элементов массива в квадратных скобках.

'use strict';
var empty = []; // Пус­той мас­сив
var primes = [2, 3, 5, 7, 11]; // Мас­сив с пя­тью чи­сло­вы­ми эле­мен­та­ми
var misc = [ 1.1, true, "a" ]; // 3 эле­мен­та раз­ных ти­пов 

Значения в литерале массива не обязательно должны быть константами – это могут быть любые выражения:

'use strict';
var base = 1024;
var table = [base, base+1, base+2, base+3];

Литералы массивов могут содержать литералы объектов или литералы других массивов:

'use strict';
var b = [[1,{x:1, y:2}], [2, {x:3, y:4}]];

Другой способ создания массива состоит в вызове конструктора Array(). Вызвать конструктор можно тремя разными способами:

'use strict';
// Вызвать конструктор без аргументов:
var a = new Array();

В этом случае будет создан пустой массив, эквивалентный литералу [].

'use strict';
// Вызвать конструктор с единственным числовым аргументом,
// определяющим длину массива:
var a = new Array(10);

В этом случае будет создан пустой массив указанной длины. Такая форма вызова конструктора Array() может использоваться для предварительного распределения памяти под массив, если заранее известно количество его элементов. Обратите внимание, что при этом в массиве не сохраняется никаких значений и даже свойства-индексы массива с именами «0», «1» и т.д. в массиве не определены.

'use strict';
// Явно указать в вызове конструктора значения первых двух или более 
// элементов массива или один нечисловой элемент:
var a = new Array(5, 4, 3, 2, 1, "testing, testing");

В этом случае аргументы конструктора становятся значениями элементов нового массива. Использование литералов массивов практически всегда проще, чем подобное применение конструктора Array().

5. Доступ к элементам массива

Доступ к элементам массива осуществляется с помощью оператора [ ]. Слева от скобок должна присутствовать ссылка на массив. Внутри скобок должно находиться произвольное выражение, возвращающее неотрицательное целое значение. Этот синтаксис пригоден как для чтения, так и для записи значения элемента массива. Следовательно, допустимы все приведенные далее JavaScript-инструкции:

'use strict';
var a = ["world"]; // Соз­дать мас­сив с од­ним эле­мен­том
var value = a[0]; // Про­чи­тать эле­мент 0
a[1] = 3.14; // За­пи­сать зна­че­ние в эле­мент 1
var i = 2;
a[i] = 3; // За­пи­сать зна­че­ние в эле­мент 2
a[i + 1] = "hello"; // За­пи­сать зна­че­ние в эле­мент 3
a[a[i]] = a[0]; // Про­чи­тать эле­мен­ты 0 и 2, за­пи­сать зна­че­ние в эле­мент 3

Напомню, что массивы являются специализированной разновидностью объектов. Квадратные скобки, используемые для доступа к элементам массива, действуют точно так же, как квадратные скобки, используемые для доступа к свойствам объекта. Интерпретатор JavaScript преобразует указанные в скобках числовые индексы в строки – индекс 1 превращается в строку "1", – а затем использует строки как имена свойств. В преобразовании числовых индексов в строки нет ничего особенного: то же самое можно проделывать с обычными объектами.

6. Длина массива

Любой массив имеет свойство length, и это свойство отличает массивы от обычных объектов JavaScript. Для плотных (т. е. неразреженных) массивов свойство length определяет количество элементов в массиве. Его значение на единицу больше самого большого индекса в массиве:

'use strict';
[].length // => 0: мас­сив не име­ет эле­мен­тов
['a','b','c'].length // => 3: наи­боль­ший ин­декс ра­вен 2, дли­на рав­на 3
'use strict';
var a = [1, 2, 3]
console.log(a.length);
delete a[1];
console.log(a.length);
a[999] = '';
console.log(a.length);

Вторая особенность в поведении, обеспечивающем работу свойства length, заключается в том, что при присваивании свойству length неотрицательного целого числа n, меньшего, чем его текущее значение, все элементы массива с индексами, большими или равными значению n, удаляются из массива:

'use strict';
var a = [1, 2, 3];
a.length = 2;
console.log(a); // [1, 2]

7. Добавление и удаление элементов массива

Мы уже видели, что самый простой способ добавить элементы в массив заключается в том, чтобы присвоить значения новым индексам:

'use strict';
a = [] // Соз­дать пус­той мас­сив.
a[0] = "zero"; // И до­ба­вить эле­мен­ты.
a[1] = "one";

8. Методы класса Array

Стандарты ECMAScript3-6 определяеют в составе Array.prototype множество удобных функций для работы с массивами, которые доступны как методы любого массива. Эти методы будут представлены в следующих подразделах. Более полную информацию можно найти в разделе Array в справочной части MDN по базовому языку JavaScript.

8.1 ES3

8.1.1 Метод join()

Метод Array.join() преобразует все элементы массива в строки, объединяет их и возвращает получившуюся строку. В необязательном аргументе методу можно передать строку, которая будет использоваться для отделения элементов в строке результата. Если строка-разделитель не указана, используется запятая.

'use strict';
var arr = ['Маша', 'Петя', 'Марина', 'Василий'];
var str = arr.join(';');
alert( str ); // Маша;Петя;Марина;Василий
alert(typeof str); // "string"

var str = arr.join();
alert( str ); // Маша,Петя,Марина,Василий

var str = arr.join(', ');
alert( str ); // Маша, Петя, Марина, Василий

8.1.2 Метод reverse()

Метод Array.reverse() меняет порядок следования элементов в массиве на обратный и возвращает переупорядоченный массив. Перестановка выполняется непосредственно в исходном массиве, т. е. этот метод не создает новый массив с переупорядоченными элементами, а переупорядочивает их в уже существующем массиве.

'use strict';
var arr = ['Маша', 'Петя', 'Марина', 'Василий'];
arr.reverse();
console.log(arr); // ["Василий", "Марина", "Петя", "Маша"]

8.1.3 Метод split()

Метод split(s), который позволяет превратить строку в массив, разбив ее по разделителю s. В примере ниже таким разделителем является строка из запятой и пробела.

'use strict';
var names = 'Маша, Петя, Марина, Василий';

var arr = names.split(', ');

for (var i = 0; i < arr.length; i++) {
  alert( 'Вам сообщение ' + arr[i] );
}

У метода split есть необязательный второй аргумент – ограничение на количество элементов в массиве. Если их больше, чем указано – остаток массива будет отброшен.

8.1.4 Метод slice()

Метод Array.slice() возвращает фрагмент, или подмассив, указанного массива. Два аргумента метода определяют начало и конец возвращаемого фрагмента. Возвращаемый массив содержит элемент, номер которого указан в первом аргументе, плюс все последующие элементы, вплоть до (но не включая) элемента, номер которого указан во втором аргументе. Если указан только один аргумент, возвращаемый массив содержит все элементы от начальной позиции до конца массива. Если какой-либо из аргументов имеет отрицательное значение, он определяет номер элемента относительно конца массива. Так, аргументу –1 соответствует последний элемент массива, а аргументу –3 – третий элемент массива с конца.

'use strict';
var arr = ['Маша', 'Петя', 'Марина', 'Василий'];
var part = arr.slice(1, 3); // ["Петя", "Марина"]

Если вообще не указать аргументов – скопируется весь массив.

8.1.5 Метод splice()

Метод Array.splice() – это универсальный метод, выполняющий вставку или удаление элементов массива. Метод splice() изменяет исходный массив, относительно которого он был вызван. Обратите внимание, что методы splice() и slice() имеют очень похожие имена, но выполняют совершенно разные операции.

Метод splice() может удалять элементы из массива, вставлять новые элементы или выполнять обе операции одновременно. Элементы массива при необходимости смещаются, чтобы после вставки или удаления образовывалась непрерывная последовательность. Первый аргумент метода splice() определяет позицию в массиве, начиная с которой будет выполняться вставка и/или удаление. Второй аргумент определяет количество элементов, которые должны быть удалены (вырезаны) из массива. Если второй аргумент опущен, удаляются все элементы массива от указанного до конца массива. Метод splice() возвращает массив удаленных элементов или (если ни один из элементов не был удален) пустой массив.

'use strict';
var a = [1,2,3,4,5,6,7,8];
a.splice(4); // Вер­нет [5,6,7,8]; a = [1,2,3,4]
a.splice(1,2); // Вер­нет [2,3]; a = [1,4]
a.splice(1,1); // Вер­нет [4]; a = [1]

Первые два аргумента метода splice() определяют элементы массива, подлежащие удалению. За этими аргументами может следовать любое количество дополнительных аргументов, определяющих элементы, которые будут вставлены в массив, начиная с позиции, указанной в первом аргументе. Например:

'use strict';
var a = [1,2,3,4,5];
a.splice(2,0,'a','b'); // Вер­нет []; a = [1,2,'a','b',3,4,5]
a.splice(2,2,[1,2],3); // Вер­нет ['a','b']; a = [1,2,[1,2],3,3,4,5]

8.1.6 Метод concat()

Метод Array.concat() создает и возвращает новый массив, содержащий элементы исходного массива, для которого был вызван метод concat(), и значения всех аргументов, переданных методу concat(). Если какой-либо из этих аргументов самявляется массивом, его элементы добавляются в возвращаемый массив. Следует, однако, отметить, что рекурсивного превращения массива из массивов в одно мерный массив не происходит. Метод concat() не изменяет исходный массив. Ниже приводится несколько примеров:

'use strict';
var a = [1,2,3];
a.concat(4, 5) // Вер­нет [1,2,3,4,5]
a.concat([4,5]); // Вер­нет [1,2,3,4,5]
a.concat([4,5],[6,7]) // Вер­нет [1,2,3,4,5,6,7]
a.concat(4, [5,[6,7]]) // Вер­нет [1,2,3,4,5,[6,7]]

8.1.7 Метод sort()

Метод Array.sort() сортирует элементы в исходном массиве и возвращает отсортированный массив. Если метод sort() вызывается без аргументов, сортировка выполняется в алфавитном порядке (для сравнения элементы временно преобразуются в строки, если это необходимо).

Для сортировки в каком-либо ином порядке, отличном от алфавитного, методу sort() можно передать функцию сравнения в качестве аргумента. Эта функция устанавливает, какой из двух ее аргументов должен следовать раньше в отсортированном списке. Если первый аргумент должен предшествовать второму, функция сравнения должна возвращать отрицательное число. Если первый аргумент должен следовать за вторым в отсортированном массиве, то функция должна возвращать число больше нуля. А если два значения эквивалентны (т.е. порядок их следования не важен), функция сравнения должна возвращать 0. Поэтому, например, для сортировки элементов массива в числовом порядке можно сделать следующее:

'use strict';
var a = [33, 4, 1111, 222];
a.sort(); // Ал­фа­вит­ный по­ря­док: 1111, 222, 33, 4
a.sort(function(a,b) { // Чи­сло­вой по­ря­док: 4, 33, 222, 1111
 return a-b; // Воз­вра­ща­ет зна­че­ние < 0, 0 или > 0
 }); // в за­ви­си­мо­сти от по­ряд­ка сор­ти­ров­ки a и b
a.sort(function(a,b) {return b-a}); // Обратный числовой порядок

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

8.2 ES5

Стандарт ECMAScript 5 определяет девять новых методов массивов, позволяющих выполнять итерации, отображение, фильтрацию, проверку, свертку и поиск. Все эти методы описываются в следующих далее подразделах.

Однако, прежде чем перейти к изучению особенностей, следует сделать некоторые обобщения, касающиеся методов массивов в ECMAScript 5. Во-первых, большинство описываемых ниже методов принимают функцию в первом аргументе и вызывают ее для каждого элемента (или нескольких элементов) массива. В случае разреженных массивов указанная функция не будет вызываться для несуществующих элементов. В большинстве случаев указанной функции передаются три аргумента: значение элемента массива, индекс элемента и сам массив. Чаще всего вам необходим будет только первый аргумент, а второй и третий аргументы можно просто игнорировать. Большинство методов массивов, введенных стандартом ECMAScript 5, которые в первом аргументе принимают функцию, также принимают второй необязательный аргумент. Если он указан, функция будет вызываться, как если бы она была методом этого второго аргумента. То есть второй аргумент будет доступен функции, как значение ключевого слова this. Значение, возвращаемое функцией, играет важную роль, но разные методы обрабатывают его по-разному. Ни один из методов массивов, введенных стандартом ECMAScript 5, не изменяет исходный массив. Разумеется, функция, передаваемая этим методам, может модифицировать исходный массив.

8.2.1 Метод forEach()

Метод forEach() выполняет обход элементов массива и для каждого из них вызывает указанную функцию. Как уже говорилось выше, функция передается методу forEach() в первом аргументе. При вызове этой функции метод forEach() будет передавать ей три аргумента: значение элемента массива, индекс элемента и сам массив. Если вас интересует только значение элемента, можно написать функцию с одним параметром – дополнительные аргументы будут игнорироваться:

'use strict';
var data = [1,2,3,4,5]; // Мас­сив, эле­мен­ты ко­то­ро­го бу­дут сум­ми­ро­вать­ся
// Най­ти сум­му эле­мен­тов мас­си­ва
var sum = 0; // На­чаль­ное зна­че­ние сум­мы 0
data.forEach(function(value) { sum += value; }); // При­ба­вить зна­че­ние к sum
sum // => 15
// Уве­ли­чить все эле­мен­ты мас­си­ва на 1
data.forEach(function(v, i, a) { a[i] = v + 1; });

8.2.2 Метод map()

Метод map() создаёт новый массив с результатом вызова указанной функции для каждого элемента массива.

'use strict';
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// теперь roots равен [1, 2, 3], а numbers всё ещё равен [1, 4, 9]

Функция map просто преобразует один массив в другой массив. Например, предположим, что у вас есть массив объектов person, но вам нужен массив name (строк):

'use strict';
var friends = [
    {id:1, name: 'Dave',age:50},
    {id:2,name: 'Kellie',age:42},
    {id:3,name: 'Max',age:12},
    {id:2,name: 'Jack',age:12}
];
var friendsNamesList = friends.map(function(element) {
    return element.name;
}); ["Dave", "Kellie", "Max", "Jack"]
// ["Dave", "Kellie", "Max", "Jack"]

8.2.3 Метод filter()

Метод filter() возвращает массив, содержащий подмножество элементов исходного массива. Передаваемая ему функция должна быть функцией-предикатом, т. е. должна возвращать значение true или false. Метод filter() вызывает функцию точно так же, как методы forEach() и map(). Если возвращается true или значение, которое может быть преобразовано в true, переданный функции элемент считается членом подмножества и добавляется в массив, возвращаемый методом. Например:

'use strict';
a = [5, 4, 3, 2, 1];
smallvalues = a.filter(function(x) { return x < 3 }); // [2, 1]
everyother = a.filter(function(x,i) { return i%2==0 }); // [5, 3, 1]

Обратите внимание, что метод filter() пропускает отсутствующие элементы в разреженных массивах и всегда возвращает плотные массивы. Чтобы уплотнить разреженный массив, можно выполнить следующие действия:

'use strict';
var dense = sparse.filter(function() { return true; });

А чтобы уплотнить массив и удалить из него все элементы со значениями undefined и null, можно использовать метод filter(), как показано ниже:

'use strict';
a = a.filter(function(x) { return x !== undefined && x != null; });

8.2.3 Методы every() и some()

Метод some() проверяет, удовлетворяет ли хоть какой-нибудь элемент массива условию, заданному в передаваемой функции.

Метод some() вызывает переданную функцию callback один раз для каждого элемента, присутствующего в массиве до тех пор, пока не найдет такой, для которого callback вернет истинное значение (значение, становящееся равным true при приведении его к типу Boolean). Если такой элемент найден, метод some() немедленно вернёт true. В противном случае, если callback вернёт false для всех элементов массива, метод some() вернёт false. Функция callback вызывается только для индексов массива, имеющих присвоенные значения; она не вызывается для индексов, которые были удалены или которым значения никогда не присваивались.

'use strict';
function isBiggerThan10(element, index, array) {
  return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10);  // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true

Метод every() проверяет, удовлетворяют ли все элементы массива условию, заданному в передаваемой функции.

Метод every() вызывает переданную функцию callback один раз для каждого элемента, присутствующего в массиве до тех пор, пока не найдет такой, для которого callback вернет ложное значение (значение, становящееся равным false при приведении его к типу Boolean). Если такой элемент найден, метод every() немедленно вернёт false. В противном случае, если callback вернёт true для всех элементов массива, метод every() вернёт true. Функция callback вызывается только для индексов массива, имеющих присвоенные значения; она не вызывается для индексов, которые были удалены или которым значения никогда не присваивались.

'use strict';
function isBigEnough(element, index, array) {
  return element >= 10;
}
[12, 5, 8, 130, 44].every(isBigEnough);   // false
[12, 54, 18, 130, 44].every(isBigEnough); // true

8.2.4 Методы reduce() и reduceRight()

8.2.5 Методы indexOf() и lastIndexOf()

Методы indexOf() и lastIndexOf() отыскивают в массиве элемент с указанным значением и возвращают индекс первого найденного элемента или –1, если элемент с таким значением отсутствует. Метод indexOf() выполняет поиск от начала массива к концу, а метод lastIndexOf() – от конца к началу.

'use strict';
a = [0,1,2,1,0];
a.indexOf(1) // => 1: a[1] = 1
a.lastIndexOf(1) // => 3: a[3] = 1
a.indexOf(3) // => -1: нет эле­мен­та со зна­че­ни­ем 3

В отличие от других методов, описанных в этом разделе, методы indexOf() и lastIndexOf() не принимают функцию в виде аргумента. В первом аргументе им передается искомое значение. Второй аргумент является необязательным: он определяет индекс массива, с которого следует начинать поиск. Если опустить этот аргумент, метод indexOf() начнет поиск с начала массива, а метод lastIndexOf() – с конца. Во втором аргументе допускается передавать отрицательные значения, которые интерпретируются как смещение относительно конца массива, как в методе splice(): значение –1, например, соответствует последнему элементу массива.

8.3 ES6

8.3.1 Методы find()

8.3.2 Методы findIndex()

8.3.3 Методы fill

8.3.4 Методы copyWithin()

*. Упражнения

1. compareFunctionNumber(a, b)

Напишите функцию compareFunctionNumber(a, b), которая принимает 2 аргумента и возвращает true если первый больше второго и false в ином случае. Приводить к числу оба аргумента внутри функции.

2. hasElement(element, arr)

Напишите функцию hasElement(element, arr), которая принимает 2 аргумента и возвращает true если element есть среди элементов массива и false в ином случае.

3. indexOfElement(element, arr)

Напишите функцию indexOfElement(element, arr), которая принимает 2 аргумента и возвращает индекс вхождения element-а в массив arr и -1 в случае отсутствия element-а в массиве.

(Linear Search)

4. binarySearch(element, arr)

Напишите функцию binarySearch(element, arr), которая работает аналогично функции indexOfElement, но использует алгоритм бинарного поиска.

(Binary Search)

5. compareFunctionString

Напишите функцию compareFunctionString(a, b), которая сравнивает строки, принимает 2 аргумента и возвращает true если первый больше второго и false в ином случае. Если тип одного из аргументов не строка, возвращать false.

7. compareFunctionType(a, type)

Напишите функцию compareFunctionType(a, type), которая принимает 2 аргумента (первый - значение, второй - строка c типом или подтипом данных) и возвращает true если первый принадлежит к указанному типу, false в ином случае.

Список типов и подтипов, которые должна обрабатывать функция:
- Undefined
- Null
- Number
- NaN
- Symbol
- Infinity
- String
- Boolean
- Object
- Array
- Map
- Set
- Function

Обратите внимание: строка 'Function', 'function', 'functiOn' должны обрабатываться одинаково (опускаем значения аргумента type в нижний регистр).

6. bubbleSort(arr)

Напишите функцию bubbleSort(arr), которая сортирует массив в порядке возрастания, и использует алгоритм сортировки пузырьком.

(Bubble Sort)

7. insertionSort(arr)

Напишите функцию insertionSort(arr), которая работает аналогично функции bubbleSort, но использует алгоритм сортировки вставкой.

(Insertion Sort)

8*. selectionSort(arr)

Напишите функцию selectionSort(arr), которая работает аналогично функции bubbleSort, но использует алгоритм сортировки выбором.

(Selection Sort)

9*. quickSort(arr)

Напишите функцию quickSort(arr), которая работает аналогично функции bubbleSort, но использует алгоритм быстрой сортировки.

(Quic kSort)

10. singleExemplar

Напишите функцию singleExemplar(a), которая принимает 1 аргумент (массив, реализовать безопасность типов) и возвращает новый массив, где все элементы уникальны в пространстве массива.

'use strict';
singleExemplar(a) { .. }
var myArray = [null, 1, 2, 2, 3, [1, 2], NaN, 'str', '1', {1}, null, NaN, 1, 3];
singleExemplar(singleExemplar); // [null, 1, 2, 3, [1, 2], NaN, 'str', '1', {1}]

Помните: NaN не равен ничему включая себя.

11. singleExemplarStrict

Напишите функцию singleExemplarStrict(a), которая принимает 1 аргумент (массив, реализовать безопасность типов) и возвращает новый массив, где все элементы уникальны в пространстве массива.

'use strict';
singleExemplar(a) { .. }
var myArray = [null, 1, 2, 2, 3, [1, 2], [1, 2, 3], [1, 2, 4], [1, 2, 3]];
singleExemplar(singleExemplar); // [null, 1, 2, 3, [1, 2], [1, 2, 3], [1, 2, 4]]

singleExemplar и singleExemplarStrict работают с примитивами работают аналогично. Но singleExemplarStrict считает массивы одинаковими если: 1 - их длины одинаковые, 2 - под одинаковыми индексами стоят одинаковые значения. В контексте функции singleExemplarStrict объекты одинаковые если: 1 - у них одинаковое количество ключей

5. singleExemplarStrict

Напишите функцию singleExemplarStrict(a), которая принимает 1 аргумент (массив, реализовать безопасность типов) и возвращает новый массив, где все элементы уникальны в пространстве массива.

'use strict';
singleExemplar(a) { .. }
var myArray = [null, 1, 2, 2, 3, [1, 2], [1, 2, 3], [1, 2, 4], [1, 2, 3]];
singleExemplar(singleExemplar); // [null, 1, 2, 3, [1, 2], [1, 2, 3], [1, 2, 4]]

singleExemplar и singleExemplarStrict работают с примитивами работают аналогично. Но singleExemplarStrict считает массивы одинаковими если: 1 - их длины одинаковые, 2 - под одинаковыми индексами стоят одинаковые значения. В контексте функции singleExemplarStrict объекты одинаковые если: 1 - у них одинаковое количество ключей

6. nodeList

var list = document.querySelectorAll('*'); - магическая строка создаст переменную list и запишет в нее объект со всеми тегами страницы.

'use strict';
var list = document.querySelectorAll('*');

6.1 Создайте массив arrList из элементов объекта list.

6.2 Создайте строку из названий всех тегов html-элементов - nodeName, используя Array.prototype.join().

6.3 Создайте строку из названий всех тегов через разделитель, используя Array.prototype.join().

6.4 Отсортируйте массив arrList от функций, используя sort().

Для корректной работы метода sort() всем элементам масива arrList нужно изменить свойство:

'use strict';
// Example
var arrList = [{x : 1}, {x : 3}, {x : 4}, {x : 2}];
arrList.forEach((e) => {
	e.toString = function() {
		return this;
	};
});

6.5 Отсортируйте элементы массива arrList по названию тега в алфавитном порядке.

6.6 Отсортируйте элементы массива массиа arrList по названию тега в обратном от задания №5 порядке (не используя Array.reverse()), результат сохранить в arrListReverse.

6.7 Заданние №6 используя Array.reverse().

6.8 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quisquam ea repellendus dicta similique quibusdam repellat delectus totam sint voluptate, quidem reiciendis labore, nihil error iusto a, placeat minus hic. Quas!.

6.9 Создайте массив arrListPlusChildren из элементов массива arrList и их потомков.

6.10 Создайте массив из 100 элементов массива arrList используя slice().

6.11 Выведите в консоль все элементы arrList не используя циклов.

6.12 Создайте массив из nodeName элементов arrList не используя циклов.

6.13 Создайте массив из withoutSpan c элементов arrList не используя циклов, откинув все span элементы.

6.14 Напишите функцию createWithoutElemens(arr, str), arr - массив элементов, str - строка с названием эле­мен­тов, которые нужно отсеять в процессе работы функции. Функция возвращает новый массив.

'use strict';
// Example
function createWithoutElemens(arr, str) {
    ...
}

var arrList = [
    {x : 1, nodeName : 'SPAN'},
    {x : 2, nodeName : 'DIV'},
    {x : 3, nodeName : 'SPAN'},
    {x : 4, nodeName : 'P'},
    {x : 5, nodeName : 'SPAN'},
    {x : 6, nodeName : 'DIV'}
];
createWithoutElemens(arrList, 'span'); // }-->
    // {x : 2, nodeName : 'DIV'},
    // {x : 4, nodeName : 'P'},
    // {x : 6, nodeName : 'DIV'}
createWithoutElemens(arrList, 'DIV'); // }-->
    // {x : 1, nodeName : 'SPAN'},
    // {x : 3, nodeName : 'SPAN'},
    // {x : 4, nodeName : 'P'},
    // {x : 5, nodeName : 'SPAN'}

6.15 Напишите аналог функции createWithoutElemens(arr, str), arr - массив элементов, str - строка с названием эле­мен­тов или массив таких строк, которые нужно отсеять в процессе работы функции. Функция возвращает новый массив.

'use strict';
// Example
function createWithoutElemens(arr, str) {
    ...
}

var arrList = [
    {x : 1, nodeName : 'SPAN'},
    {x : 2, nodeName : 'DIV'},
    {x : 3, nodeName : 'SPAN'},
    {x : 4, nodeName : 'P'},
    {x : 5, nodeName : 'SPAN'},
    {x : 6, nodeName : 'DIV'}
];
createWithoutElemens(arrList, 'span'); // }-->
    // {x : 2, nodeName : 'DIV'},
    // {x : 4, nodeName : 'P'},
    // {x : 6, nodeName : 'DIV'}
createWithoutElemens(arrList, ['SPAN', 'DIV']); // }-->
    // {x : 4, nodeName : 'P'}

7. Напишите функцию createRectangle(m, n), Функция возвращает пустой прямоугольный массив m на n. m - количество столбиков, n - количество рядов. n и m генерировать рандомно ( 2 < n < 12, 4 < m < 6).

Напишите функцию createLetter(). Функция возвращает объект - письмо.
Письмо:
- адресат (destination) - создайте массив people, где каждый элемент объект person и случайным образом получайте это поле.
- адресант (addressee) - также из массива people.
- время создания (creationTime) - случайное число 0 - new Date().getTime();
- тема (subject) - создайте функцию генерирующую тему из случайного количества слов (1 - 4) каждое слово размером 2 - 8 символов.
- сообщение (message) - создайте функцию генерирующую message, можно использовать функцию из задания №10 в уроке 6.2.

'use strict';
// Example letter
{
    destination : {
        firstName : 'Igor',
        lastName : 'Igorov',
        address : 'avenue Pupkina, 14b'
    },
    addressee : {
        firstName : 'Ivan',
        lastName : 'Ivanov',
        address : 'Vesuvius vol., 3 palm trees to the right from bar "White coconut"'
    },
    creationTime : 900000,
    subject : 'Lorem ipsum dolor.',
    message : 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. \
                Excepturi quidem culpa corporis laudantium, \
                magnam, eos numquam animi quam.'
}

Положите на случайные позиции массива созданого функциией createRectangle, случайное количество писем из случайным содержимым.

Подсчитайте количество писем в массиве.

Наклейте на каждое письмо марку с картинкой, картинки найти в google. (Добавляем поле stamp из ссылкой на картинку).