Заметки по 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() не будет перебирать их.
.
.
Спасибо за чтение!