Заметки по JavaScript#1

Буквально несколько месяцев назад я получил сообщение от бывшего ученика моего коллеги. Он выполнял некоторые задачи по кодированию; тот, где он столкнулся с проблемой, заключался в том, что ему нужно было создать программу для умножения двух матриц. Моя реакция коленного рефлекса говорила ему, что он может легко сделать это с Numpy в Python.

Но нет.

Он специально попросил решение на JavaScript. Затем он прислал мне свой код, чтобы я нашел ошибку. Как только я вернулся домой, я открыл свой ноутбук, скопировал его код в свою IDE и сразу увидел проблему. Он умножал элементы так, как если бы выполнял сложение и вычитание вместо скалярного произведения. После того, как я отладил его код и убедился, что программа работает, я запустил программу из терминала.

node index.js

Программа не удалась. Что ж, это сработало, но не дало ожидаемого значения. Две матрицы, которые нужно умножить, были такими

const a = [[3,4],[1,2]]
const b = [[7,5],[6,4]]
//expected result of a times b
[[45, 31],[19, 13]]
//my result
[[45, 31, 19, 13], [45, 31, 19, 13]]

Я такой: «Ого, что здесь произошло?». Как обычно, я попытался вставить в свой код некоторый console.log(), чтобы отслеживать значения переменных во время работы программы. После нескольких изнурительных часов регистрации переменных я сузил проблему до той части, где я создавал матрицу с нулевыми элементами для результата умножения.

Полученная матрица была n умножена на m, где n — количество строк в первой матрице, а m — количество столбцов во второй матрице. Так как я вспомнил, что делал что-то подобное несколько месяцев назад

//creating n characters of c
const repeatCharacters = (n, c) => Array(n).fill(c).join('')

Я создал ниже функцию для настройки исходной матрицы; мой план состоял в том, чтобы создать матрицу с нулевыми элементами, а затем заполнить ее позже.

//n is the number of rows in the first matrix
//set up matrix with zero elements
const result = Array(n).fill([])

Я продолжал регистрировать переменные в течение следующего часа. Поскольку в моем результате всего 8 элементов, я отслеживал количество итераций, которые выполняла моя программа. К моему удивлению, их было всего 4. Я соединил точки. Затем меня осенило, элементы ожидаемого результата повторялись в моем результате. Я наконец понял, что происходит. Я рассмеялся и начал искать в Google. Первая ссылка на Stack Overflow подтвердила мою озабоченность.

Array.fill(Array) создает копии по ссылкам, а не по значению [duplicate]

Итак, когда моя программа начала заполнять первую строку результирующей матрицы, поскольку она ссылается на тот же массив, что и вторая строка, вторая строка также обновлялась.

Узнав проблему. Я просто изменил свой код на этот

const result = Array(n).fill(n).map(() => [])

() => [] в map() будет каждый раз создавать новый экземпляр массива.

Почему мне нужно сначала заполнить массив с помощью fill(n)?

Array(n) создает массив из n неинициализированных элементов. Таким образом, map() не будет перебирать их.

.

.

Спасибо за чтение!