Arrays with numeric indices

Lecture




  1. Announcement
  2. Methods pop/push , shift/unshift
    1. End of array
    2. The beginning of the array
  3. Internal Array
    1. Impact on speed
  4. Brute force
  5. Features work length
    1. Use length to shorten the array.
  6. Creation by call new Array
    1. new Array()
    2. Multidimensional arrays
  7. Internal array representation
  8. Total

An array with numeric indices is a collection of data that stores as many values ​​as desired, and each value has its own unique number.

If a variable is a data box , then an array is a cabinet with numbered cells , each of which can contain its own data.

For example, when creating an electronic store you need to store a list of goods - for such tasks an array is invented.

Announcement

The syntax for creating a new array is square brackets with a list of elements inside.

Empty array:

var arr = [];

An array of fruits with three elements:

var fruits = [ "Яблоко" , "Апельсин" , "Слива" ];

Elements are numbered starting from zero. To get the desired element from the array, its number is indicated in square brackets:

1 var fruits = [ "Яблоко" , "Апельсин" , "Слива" ];
2
3 alert(fruits[0]); // Яблоко
4 alert(fruits[1]); // Апельсин
5 alert(fruits[2]); // Слива

Element can always be replaced:

fruits[2] = 'Груша' ; // теперь ["Яблоко", "Апельсин", "Груша"]
... Or add:

fruits[3] = 'Лимон' ; // теперь ["Яблоко", "Апельсин", "Груша", "Лимон"]

The total number of elements stored in the array is contained in its length property:

1 var fruits = [ "Яблоко" , "Апельсин" , "Груша" ];
2
3 alert(fruits.length); // 3

Through alert you can output the entire array. In this case, its elements will be listed separated by commas:

1 var fruits = [ "Яблоко" , "Апельсин" , "Груша" ];
2
3 alert(fruits); // Яблоко,Апельсин,Груша

An array can store any number of elements of any type. Including, strings, numbers, objects, etc .:

1 // микс значений
2 var arr = [ 1, 'Имя' , { name: 'Петя' }, true ];
3
4 // получить объект из массива и тут же -- его свойство
5 alert( arr[2].name ); // Петя

Importance: 5

How to get the last element from an arbitrary array?

We have an array of goods . How many elements in it - we do not know, but we can read from goods.length . Write code to get the last item goods .

Decision

The last element has an index of 1 less than the length of the array.

For example:

var fruits = [ "Яблоко" , "Груша" , "Слива" ];

The array length of this array fruits.length is 3 . Here, “Apple” has index 0 , “Pear” - index 1 , “Plum” - index 2 .

That is, for the array of length goods :

var lastItem = goods[goods.length-1]; // получить последний элемент

[Open task in new window]

Importance: 5

How to add an element to the end of an arbitrary array?

We have an array of goods . Write code to add Computer to its end.

Decision

The current last item has an index of goods.length-1 . Hence, the index of the new element will be goods.length :

goods[goods.length] = 'Компьютер'

[Open task in new window]

Methods pop/push , shift/unshift

One of the applications of the array is a queue. In classical programming, an ordered collection of elements is so called, such that elements are added to the end, and processed from the beginning.

In real life, this data structure is very common. For example, the queue of messages to be sent.

Close to the queue is another data structure: the stack. This is such a collection of elements in which new elements are added to the end and taken from the end.

For example, a stack is a deck of cards in which new cards are placed on top, and are taken - also on top.

In order to implement these data structures, and simply for more convenient work with the beginning and end of the array, there are special methods.

End of array

pop
Removes the last element from the array and returns it:

1 var fruits = [ "Яблоко" , "Апельсин" , "Груша" ];
2
3 alert( fruits.pop() ); // удалили "Груша"
4
5 alert(fruits); // Яблоко, Апельсин

push
Adds an element to the end of the array:

1 var fruits = [ "Яблоко" , "Апельсин" ];
2
3 fruits.push( "Груша" );
4
5 alert(fruits); // Яблоко, Апельсин, Груша

It is a complete analogue of fruits[fruits.length] = ...

The beginning of the array

shift
Removes the first element from the array and returns it:
1 var fruits = [ "Яблоко" , "Апельсин" , "Груша" ];
2
3 alert( fruits.shift() ); // удалили Яблоко
4
5 alert(fruits); // Апельсин, Груша
unshift
Adds an element to the beginning of the array:
1 var fruits = [ "Апельсин" , "Груша" ];
2
3 fruits.unshift( 'Яблоко' );
4
5 alert(fruits); // Яблоко, Апельсин, Груша

  Arrays with numeric indices

The push and unshift can add several elements at once:

1 var fruits = [ "Яблоко" ];
2
3 fruits.push( "Апельсин" , "Персик" );
4 fruits.unshift( "Ананас" , "Лимон" );
5
6 // результат: ["Ананас", "Лимон", "Яблоко", "Апельсин", "Персик"]
7 alert(fruits);

Importance: 5

The task of 5 steps lines:

  1. Create an array of styles with elements “Jazz”, “Blues”.
  2. Add Rock n Roll to the end
  3. Replace the last but one value from the end to “Classic”. The replacement code for the last but one value should work for arrays of any length.
  4. Remove the first value of the array and output its alert .
  5. Add “Rap” and “Reggae” to the beginning.

The array as a result of each step:

1 Джаз, Блюз
2 Джаз, Блюз, Рок-н-Ролл
3 Джаз, Классика, Рок-н-Ролл
4 Классика, Рок-н-Ролл
5 Рэп, Регги, Классика, Рок-н-Ролл

Decision
[Open task in new window]

Importance: 3

Write the code to output the alert random value from the array:

var arr = [ "Яблоко" , "Апельсин" , "Груша" , "Лимон" ];

PS Code to generate a random integer from min to max inclusive:

var rand = min + Math.floor( Math.random() * (max+1-min) );

Decision

For output you need a random number from 0 to arr.length-1 inclusive.

1 var arr = [ "Яблоко" , "Апельсин" , "Груша" , "Лимон" ];
2
3 var rand = Math.floor( Math.random() * arr.length );
4
5 alert(arr[rand]);

[Open task in new window]

Importance: 4

Write a code that:

  • Queries the values ​​in turn using the prompt and saves them in an array.
  • Ends input as soon as the visitor enters a blank line, not a number, or clicks Cancel.
  • Displays the sum of all array values.

The demo page tutorial / intro / array / calculator.html shows the result.

Decision

Solution: tutorial / intro / array / calculator.html

Before the prompt + to convert to a number, otherwise the calculator will add lines.

[Open task in new window]

Internal Array

An array is an object where numbers are selected as keys, with additional methods and the length property.

Since this is an object, it is passed to the function by reference:

01 function eat(arr) {
02    arr.pop();
03 }
04
05 var arr = [ "нам" , "не" , "страшен" , "серый" , "волк" ]
06
07 alert(arr.length); // 5
08 eat(arr);
09 eat(arr);
10 alert(arr.length); // 3, в функцию массив не скопирован, а передана ссылка

Another consequence is that you can assign any properties to an array.

For example:

1 var fruits = []; // создать массив
2
3 fruits[99999] = 5; // присвоить свойство с любым номером
4
5 fruits.age = 25; // назначить свойство со строковым именем

.. But arrays are invented in order to make it convenient to work with ordered, numbered data . To do this, they have special methods and the length property.

As a rule, there is no reason to use an array as a normal object, although technically it is possible.

Array output with “holes”

If there are missing indexes in the array, then in the output in most browsers “extra” commas appear, for example:

1 var a = [];
2 a[0] = 0;
3 a[5] = 5;
4
5 alert(a); // 0,,,,,5

These commas appear because the array output algorithm goes from 0 to arr.length and displays everything separated by commas. The absence of values ​​gives several commas in a row.

Impact on speed

The push/pop methods are fast, and shift/unshift is slow.

To understand why working with the end of an array is faster than with its beginning, let us analyze what is happening in more detail.

The shift operation performs two actions:

  1. Remove item at the beginning.
  2. Update the internal length property.

At the same time, since all the elements are in their cells, simply clearing the cell with the number 0 not enough. It is also necessary to move all the cells 1 down (changes are highlighted in red in the figure):

fruits.shift(); // убрать 1 элемент с начала
  Arrays with numeric indices

The more elements in the array, the longer they move.

unshift works in a similar unshift : to add an element to the beginning of an array, you must first transfer all existing ones.

The push/pop methods have no such problems. To remove an element, the pop method clears the cell and shortens the length .

fruits.pop(); // убрать 1 элемент с конца

  Arrays with numeric indices

Similarly, push works.

Brute force

To iterate over elements, a cycle is usually used:

1 var arr = [ "Яблоко" , "Апельсин" , "Груша" ];
2
3 for ( var i=0; i<arr.length; i++) {
4    alert( arr[i] );
5 }

Do not use for..in for arrays

Since the array is an object, the for..in option is also possible:

1 var arr = [ "Яблоко" , "Апельсин" , "Груша" ];
2
3 for ( var key in arr) {
4    alert( arr[key] ); // Яблоко, Апельсин, Груша
5 }

The disadvantages of this method are:

  • The for..in will display all the properties of the object, not just digital.

    In the browser, when working with page objects, there are collections of elements that look like arrays, but have additional non-digital properties that will be visible in the for..in loop.

    There are also libraries that provide such collections. For example jQuery. It looks like an array, but there are additional properties. For searching only digital properties, a for(var i=0; i<arr.length...) loop is needed for(var i=0; i<arr.length...)

  • The for (var i=0; i<arr.length; i++) loop for (var i=0; i<arr.length; i++) in modern browsers runs 10-100 times faster. It would seem that it is more complicated in appearance, but the browser optimizes such cycles in a special way.

In short: the for(var i=0; i<arr.length...) loop for(var i=0; i<arr.length...) safer and faster.

Features work length

Built-in methods for working with an array automatically update its length .

Length is not the number of elements in the array, but the последний индекс + 1 . So it is arranged.

This is easy to see in the following example:

1 var arr = [];
2 arr[1000] = true ;
3
4 alert(arr.length); // 1001

In general, if your array elements are numbered randomly or with large gaps, then you should consider using a regular object.

Arrays are designed specifically for working with a continuous ordered collection of elements.

Use length to shorten the array.

Usually we don’t need to change the length ourselves ... But there is one trick that can be pulled.

When the length decreased, the array is shortened. Moreover, this process is irreversible, i.e. even if you then return the length back - the values ​​will not be restored:

1 var arr = [1, 2, 3, 4, 5];
2
3 arr.length = 2; // укоротить до 2 элементов
4 alert(arr); // [1, 2]
5
6 arr.length = 5; // вернуть length обратно, как было
7 alert(arr[3]); // undefined: значения не вернулись

The easiest way to clear an array is arr.length=0 .

Creation by call new Array

new Array()

There is another syntax for creating an array:

var arr = new Array ( "Яблоко" , "Груша" , "и т.п." );

It is rarely used because square brackets [] shorter.

In addition, he has one feature. Usually new Array(элементы, ...) creates an array of these elements, but if it has one argument, and this number, it creates an array without elements, but with a given length .

1 var arr = new Array(2,3); // создает массив [2, 3]
2
3 arr = new Array(2); // создаст массив [2] ?
4
5 alert(arr[0]); // нет! у нас массив без элементов, длины 2

What is this “array without elements, but with length”? How is this possible?

It turns out that it is very possible and corresponds to the {length: 2} object. The resulting array behaves as if its elements are undefined .

This can be an unexpected surprise, so square brackets are usually used.

Multidimensional arrays

Arrays in JavaScript can contain other arrays as elements. This can be used to create multi-dimensional arrays, such as matrices:

1 var matrix = [
2    [1, 2, 3],
3    [4, 5, 6],
4    [7, 8, 9]
5 ];
6
7 alert(matrix[1][1]); // центральный элемент

Internal array representation

Hardcore coders only

This section refers to the internal structure of the data structure and requires special knowledge. It is not required to read.

Numerical arrays, according to the specification, are objects to which a number of properties, methods, and automatic length are added. But inside they are usually arranged differently.

Modern interpreters try to optimize them and store in memory not in the form of a hash table, but in the form of a contiguous memory area, just like in the C language. Array operations are also optimized, especially if the array stores only one type of data, for example only numbers. The generated instruction set for the processor is very efficient.

As a rule, the interpreter does it, but the programmer should not interfere.

In particular:

  • Do not set arbitrary properties to the array, such as arr.test = 5 . That is, to work exactly as with an array, and not as with an object.
  • Fill array continuously. As soon as the browser encounters the unusual behavior of the array, for example, the value arr[0] , and then immediately arr[1000] , it starts working with it as with a normal object. Typically, this entails converting it to a hash table.

If you follow these principles, then the arrays will take up less memory and run faster.

Total

Arrays exist to work with an ordered set of elements.

Announcement:

1 // предпочтительное
2 var arr = [ элемент1, элемент2... ];
3
4 // new Array
5 var arr = new Array( элемент1, элемент2...);

At the same time, the new Array(число) creates an array of a given length, without elements . To avoid errors, the first syntax is preferred.

The length property is the length of the array. More specifically, the last array index is plus 1 . If you manually reduce it, the array will be shortened. If length greater than the actual number of elements, then the missing elements are undefined .

The array can be used as a queue or stack.

Operations with the end of the array:

  • arr.push(элемент1, элемент2...) adds elements to the end.
  • var elem = arr.pop() removes and returns the last element.

Operations with the beginning of the array:

  • arr.unshift(элемент1, элемент2...) adds elements to the beginning.
  • var elem = arr.shift() removes and returns the first element.

These operations renumber all elements, so they are slow.

In the next chapter, we will look at other methods for working with arrays.

Importance: 3

What will this code output?

1 var arr = [1,2,3];
2
3 var a = arr;
4 a[0] = 5;
5
6 alert(arr[0]);
7 alert(a[0]);

Decision

1 var arr = [1,2,3];
2
3 var a = arr; // (*)
4 a[0] = 5;
5
6 alert(arr[0]);
7 alert(a[0]);

The code will output 5 in both cases, since the array is an object. In the line (*) , the reference to it is copied into the variable a , and the object itself is still one in memory; it reflects changes made through a or arr .

If you just need to copy the array, then this can be done, for example, as follows:

var a = [];
for ( var i=0; i<arr.length; i++) a[i] = arr[i];

[Open task in new window]

Importance: 3

Create a find(arr, value) function that searches the arr array for the value value and returns its number if found, or -1 if not found.

For example:

1 arr = [ "test" , 2, 1.5, false ];
2
3 find(arr, "test" ); // 0
4 find(arr, 2); // 1
5 find(arr, 1.5); // 2
6
7 find(arr, 0); // -1

Decision

Possible Solution:

1 function find(array, value) {
2
3    for ( var i=0; i<array.length; i++) {
4      if (array[i] == value) return i;
5    }
6    
7    return -1;
8 }

However, it is a mistake, because == comparison does not distinguish between 0 and false .

Therefore it is better to use === . In addition, in the modern JavaScript standard there is a built-in function Array # indexOf, which works in this way. It makes sense to use it if the browser supports it.

01 function find(array, value) {
02    if (array.indexOf) { // если метод существует
03      return array.indexOf(value);
04    }
05
06    for ( var i=0; i<array.length; i++) {
07      if (array[i] === value) return i;
08    }
09    
10    return -1;
11 }
12
13 var arr = [ "a" , -1, 2, "b" ];
14
15 var index = find(arr, 2);
16
17 alert(index);

... But an even better option would be to determine find differently depending on the browser support for the indexOf method:

01 // создаем пустой массив и проверяем поддерживается ли indexOf
02 if ( [].indexOf ) {
03
04    var find = function (array, value) {
05      return array.indexOf(value);
06    }
07
08 } else {
09    var find = function (array, value) {
10      for ( var i=0; i<array.length; i++) {
11        if (array[i] === value) return i;
12      }
13    
14      return -1;
15    }
16
17 }

This method is best because It does not require find to check indexOf support every time it indexOf .

[Open task in new window]

Importance: 3

Create a filterRange(arr, a, b) function that takes an array of arr numbers and returns a new array that contains only numbers from arr in the range from a to b . That is, the check has the form a ≤ arr[i] ≤ b .
The function should not change arr .

Work example:

1 var arr = [5, 4, 3, 8, 0];
2
3 var filtered = filterRange(arr, 3, 5);
4 // теперь filtered = [5, 4, 3]
5 // arr не изменился

Decision
Solution Step 1

Algorithm of the decision:

  1. Create a temporary empty array var results = [] .
  2. Go through the elements of arr in a loop and fill it.
  3. Return the results .
Solution Step 2

Code: tutorial / intro / array / filterRange.html.

[Open task in new window]

Importance: 3

An integer greater than 1 is called simple if it is not completely divided into anything other than itself and 1 .

The ancient algorithm "Sieve of Eratosthenes" to search for all prime numbers up to n looks like this:

  1. Create a list of consecutive numbers from 2 to n : 2, 3, 4, ..., n .
  2. Let p=2 , this is the first prime number.
  3. Cross out all subsequent numbers in the list with a difference in p , i.e. 2p, 3p, 4p , etc. In the case of p=2 this will be 4,6,8...
  4. Change the value of p to the first unclaimed number after p .
  5. Repeat steps 3-4 until p 2 < n .
  6. All remaining unclosed numbers are prime.

See also the animation of the algorithm.

Implement Sieve Eratosthenes in JavaScript. Find all prime numbers up to 100 and print their sum.

Decision

Their sum is 1060 .

Solution: tutorial / intro / array / sieve.html.

[Open task in new window]

Importance: 2

The input is an array of numbers, for example: arr = [1, -2, 3, 4, -9, 6] .

The task is to find a continuous subarray arr , the sum of the elements of which is maximal.

Your function should return only this amount.

For example:

1 getMaxSubSum([-1, 2, 3 , -9]) = 5 (сумма выделенных)
2 getMaxSubSum([ 2, -1, 2, 3 , -9]) = 6
3 getMaxSubSum([-1, 2, 3, -9, 11 ]) = 11
4 getMaxSubSum([-2, -1, 1, 2 ]) = 3
5 getMaxSubSum([ 100 , -9, 2, -3, 5]) = 100
6 getMaxSubSum([ 1, 2, 3 ]) = 6 (неотрицательные - берем всех)

If all elements are negative, then we do not take a single element and consider the sum to be zero:

getMaxSubSum([-1, -2, -3]) = 0

Try to come up with a solution that works for O (n 2 ), and better for O (n) operations.

Decision
Hint for O (n 2 )

You can simply calculate for each element of the array all the amounts that begin with it.

For example, for [-1, 2, 3, -9, 11] :

01 // Начиная с -1:
02 -1
03 -1 + 2
04 -1 + 2 + 3
05 -1 + 2 + 3 + (-9)
06 -1 + 2 + 3 + (-9) + 11
07
08 // Начиная с 2:
09 2
10 2 + 3
11 2 + 3 + (-9)
12 2 + 3 + (-9) + 11
13
14 // Начиная с 3:
15 3
16 3 + (-9)
17 3 + (-9) + 11
18
19 // Начиная с -9
20 -9
21 -9 + 11
22
23 // Начиная с -11
24 -11

Make a nested loop, which at the external level runs through the elements of the array, and at the internal level it forms all sums of elements that start from the current position.

O (n 2 ) Solution

Solution through nested loop:

01 function getMaxSubSum(arr) {
02    var maxSum = 0; // если совсем не брать элементов, то сумма 0
03
04    for ( var i=0; i<arr.length; i++) {
05      var sumFixedStart = 0;
06      for ( var j=i; j<arr.length; j++) {
07        sumFixedStart += arr[j];
08        maxSum = Math.max(maxSum, sumFixedStart);
09      }
10    }
11
12    return maxSum;
13 }
14
15 alert( getMaxSubSum([-1, 2, 3, -9]) ); // 5
16 alert( getMaxSubSum([-1, 2, 3, -9, 11]) ); // 11
17 alert( getMaxSubSum([-2, -1, 1, 2]) ); // 3
18 alert( getMaxSubSum([1, 2, 3]) ); // 6
19 alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100

Algorithm for O (n)

We will go through the array and accumulate the current partial sum in some variable s . If at some point s turns out to be negative, then we simply assign s=0 . It is argued that the maximum of all values ​​of the variable s that occurred during the operation will be the answer to the problem.

We prove this algorithm.

In fact, consider the first point in time when the sum s has become negative. This means that, starting from the zero partial sum, we finally came to a negative partial sum, which means that all this array prefix, as well as any of its suffixes, have a negative sum.

Consequently, there can be no further benefit from this whole array prefix: it can only give a negative increase in the answer.

Solution for O (n)

01 function getMaxSubSum(arr) {
02    var maxSum = 0, partialSum = 0;
03    for ( var i=0; i<arr.length; i++) {
04      partialSum += arr[i];
05      maxSum = Math.max(maxSum, partialSum);
06      if (partialSum < 0) partialSum = 0;
07    }
08    return maxSum;
09 }
10
11
12 alert( getMaxSubSum([-1, 2, 3, -9]) ); // 5
13 alert( getMaxSubSum([-1, 2, 3, -9, 11]) ); // 11
14 alert( getMaxSubSum([-2, -1, 1, 2]) ); // 3
15 alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
16 alert( getMaxSubSum([1, 2, 3]) ); // 6
17 alert( getMaxSubSum([-1, -2, -3]) ); // 0

You can also read information about the algorithm here: http: // e-

created: 2014-10-07
updated: 2021-03-13
132640



Rating 9 of 10. count vote: 2
Are you satisfied?:



Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Scripting client side JavaScript, jqvery, BackBone

Terms: Scripting client side JavaScript, jqvery, BackBone