betacode

Массивы в TypeScript

  1. Что такое массив?
  2. Доступ к элементам массива
  3. Нецелочисленный индекс
  4. Цикл по массиву
  5. Массив, доступный только для чтения
  6. Методы массива
  7. forEach(..)
  8. every(..)
  9. sort(..)
  10. filter(..)

1. Что такое массив?

В TypeScript массив - это специальный тип данных, используемый для хранения множества значений множества различных типов данных. В отличие от Java, массив в TypeScript может автоматически увеличивать свою длину при необходимости.
Массив Type[] в TypeScript имеет тот же способ хранения данных, что и Map<Integer,Type> в Java. Мы проясним это в статье.
Подобно JavaScript, TypeScript поддерживает два синтаксиса для создания массива:
Синтаксис типа[]:
Синтаксис Type[] является общим синтаксисом для объявления массива, который используется во многих разных языках и, конечно, включает в себя TypeScript:
Например: Объявите массив только для хранения элементов типа string. Компилятор of TypeScript сообщит об ошибке, если вы случайно добавите в массив элемент другого типа.
let fruits: string[];
fruits = ['Apple', 'Orange', 'Banana'];

// Or:
let fruits: string[] = ['Apple', 'Orange', 'Banana'];
Например: Объявите массив с элементами разных типов данных:
let arr = [1, 3, 'Apple', 'Orange', 'Banana', true, false];
Например: Объявите массив с типом данных объединения (union data type) - numberstring:
let values: (string | number)[] = ['Apple', 'Orange', 1, 2, 'Banana', 3];
Синтаксис массива <Type>:
Объявление массива на основе синтаксиса Array<Type> также эквивалентно синтаксису Type[], Нет никакой разницы.
let fruits: Array<string>;
fruits = ['Apple', 'Orange', 'Banana'];

// Or:
let fruits: Array<string> = ['Apple', 'Orange', 'Banana'];
В TypeScript синтаксис Type[] является просто сокращением синтаксиса Array<Type>. Массивы в TypeScript являются объектами интерфейса Array<T>, поэтому они соответствуют стандартам, определенным в этом интерфейсе (см. Ниже).
Например: Объявите массив с типом данных объединения - numberstring:
let values: Array<string | number> = ['Apple', 'Orange', 1, 2, 'Banana', 3];

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

К элементам массива можно получить доступ, используя индекс элемента, например, myArray[index]. Индекс массива начинается с 0, поэтому индекс первого элемента равен 0, индекс второго элемента равен единице и так далее.
Например:
array_ex1.ts
function array_ex1_test() {
    var myArray: number[] = [4, 8, 13, 6, 55, 41, 42, 99, 1];

    console.log("Length of myArray: " + myArray.length); // 9 Elements
    console.log("Element at index 0: " + myArray[0]); // 4
    console.log("Element at index 1: " + myArray[1]); // 8
    console.log("Element at index 4: " + myArray[4]); // 55
}
array_ex1_test(); // Call the function
Output:
Length of myArray: 9
Element at index 0: 4
Element at index 1: 8
Element at index 4: 55
Вы также можете присвоить новые значения элементам массива с помощью их индекса:
array_ex2.ts
function array_ex2_test()  {
    var fruits: string[] = ["Acerola", "Apple", "Banana" ];  

    console.log(`fruits[0] = ${fruits[0]}`);
    console.log(`fruits[1] = ${fruits[1]}`);
    
    console.log("--- Assign new values to elements ... --- ")
    fruits[0] = "Breadfruit";
    fruits[1] = "Carambola";

    console.log(`fruits[0] = ${fruits[0]}`);
    console.log(`fruits[1] = ${fruits[1]}`);
}
array_ex2_test(); // Call the function.
Output:
fruits[0] = Acerola
fruits[1] = Apple
--- Assign new values to elements ... ---
fruits[0] = Breadfruit
fruits[1] = Carambola
В отличие от Java, массивы в TypeScript могут автоматически увеличиваться в длину при необходимости. В приведенном ниже примере у нас есть массив с начальной длиной 3. Мы присваиваем значения элементам с индексами 6 и 7. Теперь длина массива будет равна 8.
array_ex3.ts
function array_ex3_test()  {
    var fruits: string[] = ["Acerola", "Apple", "Banana" ];   
    console.log(`Array length is ${fruits.length}`); // 3
    
    console.log(" --- Set the value for the elements at index 6 and 7. ---");  
    // Add more elements to the array.
    fruits[6] = "Breadfruit";
    fruits[7] = "Carambola";
    console.log(`Now Array length is ${fruits.length}`); // 8  indexes: [0,1,2,3,4,5,6,7]

    console.log(`Element at index 4: ${fruits[4]}`); // undefined
    console.log(`Element at index 5: ${fruits[5]}`); // undefined
}
array_ex3_test(); // Call the function.
Output:
Array length is 3
 --- Set the value for the elements at index 6 and 7. ---
Now Array length is 8
Element at index 4: undefined
Element at index 5: undefined

3. Нецелочисленный индекс

В отличие от Java и C#. Массивы TypeScript принимают нецелочисленные индексы, которые также принимают отрицательные индексы. Однако такие элементы не учитываются при определении длины массива.
array_idx_ex1.ts
function array_idx_ex1_test()  {
    var fruits: string[] = ["Acerola", "Apple", "Banana" ];   
    console.log(`Array length is ${fruits.length}`); // 3
    
    console.log(" --- Set the value for the elements at indexes 6, 10.5 and -100 ---");  
    // Add more elements to the array.
    fruits[6] = "Breadfruit";
    fruits[10.5] = "Carambola"; // !!!!!!!!!!
    fruits[-100] = "Grapefruit"; // !!!!!!!!!!
    console.log(`Now Array length is ${fruits.length}`); // 7  indexes: [0,1,2,3,4,5,6]

    console.log(`Element at index 4: ${fruits[4]}`); // undefined
    console.log(`Element at index 5: ${fruits[5]}`); // undefined
    console.log(`Element at index 10.5: ${fruits[10.5]}`); // Carambola
    console.log(`Element at index -100: ${fruits[-100]}`); // Grapefruit
}
array_idx_ex1_test(); // Call the function.
Output:
Array length is 3
--- Set the value for the elements at indexes 6, 10.5 and -100 ---
Now Array length is 7
Element at index 4: undefined
Element at index 5: undefined
Element at index 10.5: Carambola
Element at index -100: Grapefruit

4. Цикл по массиву

В принципе, существует два синтаксиса цикла for для доступа к элементам массива.
Syntax 1:
Этот синтаксис разрешает доступ только к элементам с неотрицательным целочисленным индексом.
for(let idx =0; idx < fruits.length; idx++) {
    console.log(`Element at index ${idx} is ${fruits[idx]}`);  
}
Например:
array_for_loop_ex1.ts
function array_for_loop_ex1_test()  {
    var fruits: string[] = ["Acerola", "Apple", "Banana" ];   
    console.log(`Array length is ${fruits.length}`); // 3 indexes [0,1,2]
    
    console.log(" --- Set the value for the elements at indexes 6 and 10.5 ---");  
    // Add more elements to the array.
    fruits[6] = "Breadfruit";
    fruits[10.5] = "Carambola"; // !!!!!!!!!!

    for(let idx =0; idx < fruits.length; idx++) {
        console.log(`Element at index ${idx} is ${fruits[idx]}`);  
    }
}
array_for_loop_ex1_test(); // Call the function.
Output:
Element at index 0 is Acerola
Element at index 1 is Apple
Element at index 2 is Banana
Element at index 3 is undefined
Element at index 4 is undefined
Element at index 5 is undefined
Element at index 6 is Breadfruit
Syntax 2:
Синтаксис цикла for ниже обращается только к индексам, которые фактически существуют в массиве, включая индексы, которые не являются целыми или отрицательными числами.
for(let idx in fruits) {
    console.log(`Element at index ${idx} is ${fruits[idx]}`);  
}
Например:
array_for_loop_ex2.ts
function array_for_loop_ex2_test()  {
    var fruits: string[] = ["Acerola", "Apple", "Banana" ];   
    console.log(`Array length is ${fruits.length}`); // 3 indexes [0,1,2]
    
    console.log(" --- Set the value for the elements at indexes 6 and 10.5 ---");  
    // Add more elements to the array.
    fruits[6] = "Breadfruit";
    fruits[10.5] = "Carambola"; // !!!!!!!!!!

    for(let idx in fruits) {
        console.log(`Element at index ${idx} is ${fruits[idx]}`);  
    }
}
array_for_loop_ex2_test(); // Call the function.
Output:
Element at index 0 is Acerola
Element at index 1 is Apple
Element at index 2 is Banana
Element at index 6 is Breadfruit
Element at index 10.5 is Carambola
Other Examples:
Например: Массив, содержащий элементы типа string, преобразует все свои элементы в прописные буквы (uppercase).
array_for_loop_ex3.ts
function array_for_loop_ex3_test()  {
    var fruits: string[] = ["Acerola", "Apple", "Banana" ];   

    for(let idx in fruits) {
        let v = fruits[idx];
        if(v)  {
            fruits[idx] = v.toUpperCase();
        }
    }
    // Print elements:
    for(let idx in fruits) {
        console.log(`Element at index ${idx} is ${fruits[idx]}`);  
    }  
}
array_for_loop_ex3_test(); // Call the function.
Output:
Element at index 0 is ACEROLA
Element at index 1 is APPLE
Element at index 2 is BANANA

5. Массив, доступный только для чтения

Используйте ключевое слово readonly в объявлении массива, чтобы создать массив, доступный только для чтения (read only). Это означает, что вы не можете добавлять, удалять или обновлять элементы массива.
  • Примечание: Ключевое слово readonly разрешено только в синтаксисе Type[], а не в синтаксисе Array<Type>.
let okArray1 : readonly string[] = ["Acerola", "Apple", "Banana" ]; // OK

let okArray2 : readonly string[];
    okArray2 = ["Acerola", "Apple", "Banana" ]; // OK

let errorArray1 : readonly Array<String>; // Compile Error!!!
Без использования ключевого слова readonly вы также можете объявить массив только для чтения с помощью интерфейса ReadonlyArray<T>:
let okArray3 : ReadonlyArray<String>; // OK
Например:
let fruits: readonly string[] = ["Acerola", "Apple", "Banana" ];  // OK   

fruits[1] = "Breadfruit"; // Compile Error!!!!!!  


let years: ReadonlyArray<number> = [2001, 2010, 2020 ];  // OK   

years[1] = 2021; // Compile Error!!!!!!

6. Методы массива

В TypeScript массив является объектом интерфейса Array<T>, поэтому у него есть методы, определенные в этом интерфейсе.
interface Array<T> {
  length: number;
  toString(): string;
  toLocaleString(): string;
  pop(): T | undefined;
  push(...items: T[]): number;
  concat(...items: ConcatArray<T>[]): T[];
  concat(...items: (T | ConcatArray<T>)[]): T[];
  join(separator?: string): string;
  reverse(): T[];
  shift(): T | undefined;
  slice(start?: number, end?: number): T[];
  sort(compareFn?: (a: T, b: T) => number): this;
  splice(start: number, deleteCount?: number): T[];
  splice(start: number, deleteCount: number, ...items: T[]): T[];
  unshift(...items: T[]): number;
  indexOf(searchElement: T, fromIndex?: number): number;
  lastIndexOf(searchElement: T, fromIndex?: number): number;
  every<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): this is S[];
  every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
  some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
  forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
  map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
  filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
  filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
  reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
  reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
  reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
  reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
  reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
  reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
  [n: number]: T;
}

7. forEach(..)

forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
Выполняет указанное действие для каждого элемента массива.
Например:
array_forEach_ex1.ts
function array_forEach_ex1_test()  {
    let fruits:   string[] = ["Acerola", "Apple", "Banana" ];  // OK  
    // A callback function.
    var callback = function(value:string, index:number, thisArray:string[]) {
        if(index % 2 == 0) {
            console.log(value);
        } else {
            console.log(value.toUpperCase());
        }
    }
    fruits.forEach(callback);
}
array_forEach_ex1_test(); // Call the function.
Output:
Acerola
APPLE
Banana

8. every(..)

every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
Проверяет, все ли элементы массива проходят проверку указанной функции.
predicate: Функция для проверки каждого элемента массива.
Например: Массив состоит из лет. Проверьте, все ли годы больше 1990 года.
array_every_ex1.ts
function array_every_ex1_test() {
    let years: number[] = [2001, 1995, 2007, 2010, 2020];   
    // Arrow function.
    var predicate =  (value: number, index: number, thisArray: number[]) => {
        return value > 1990;
    }
    var ok: boolean = years.every(predicate);
    console.log(`All years > 1990? ${ok}`); // true
}
array_every_ex1_test(); // Call the function.

9. sort(..)

sort(compareFn?: (a: T, b: T) => number): this;
Сортирует этот массив на основе указанной функции и возвращает этот массив. Если функция не предусмотрена, элементы массива будут отсортированы в соответствии с естественными правилами.
Например: Сортировка массива string:
array_sort_ex1.ts
function array_sort_ex1_test() {
    let fruits: string[] = ["Banana", "Acerola", "Apple", "Carambola", "Breadfruit"];
    // Compare Function:
    var compareFn = (a: string, b: string) => {
        // v > 0 --> a > b
        // v = 0 --> a == b
        // v < 0 --> a < b
        let v: number = a.localeCompare(b);
        return v;
    }
    fruits.sort(compareFn);
    console.log("--- after sorting --- ");
    console.log(fruits);
}
array_sort_ex1_test(); // Call the function.
Output:
--- after sorting ---
[ 'Acerola', 'Apple', 'Banana', 'Breadfruit', 'Carambola' ]

10. filter(..)

filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];

filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
Возвращает новый массив элементов, прошедших проверку указанной функции.
Например: Массив состоит из лет, отфильтруйте новый массив, состоящий только из четных лет.
array_filter_ex1.ts
function array_filter_ex1_test() {
    let years: number[] = [2001, 1995, 2007, 2010, 2020];
    // Filter even value.
    var predicate = (value: number, index: number, thisArray: number[]) => {
        return value % 2 == 0;
    }
    var evenYears: number[] = years.filter(predicate);
    console.log(" --- Even Years: --- ");
    console.log(evenYears);
}
array_filter_ex1_test(); // Call the function.
Output:
--- Even Years: ---
[ 2010, 2020 ]