Я пытаюсь создать функцию для создания треугольника паскалей в javascript с функцией Array.map().
Собственно, я использую эту функцию:
let triangle = [],
maxRows = 5
// Columns
for (let i = 0; i < maxRows; i++) {
// Create new row
let row = [];
// Fill row
for (let j = 0; j <= i; j++) {
row.push(j === 0 || j === i ? 1 : triangle[i - 1][j - 1] + triangle[i - 1][j]);
}
// Add row to triangle
triangle.push(row);
}
console.info(triangle)
Но я хотел бы использовать что-то вроде этого:
let triangle = Array(maxRows).fill().map((row, i) => {
return Array(i + 1).fill().map((_, j) => {
return j === 0 || j === i ? 1 : triangle[i - 1][j - 1] + triangle[i - 1][j];
});
});
Есть ли способ получить доступ к переменной треугольника внутри второго Array.map()?
Просто понял, что это не сработает для вашего кода, так как то, что вы получаете с Array(maxRows).fill()
, представляет собой массив undefined
. .map()
на самом деле не изменяет вашу переменную triangle
на месте, она возвращает новый массив после того, как это будет сделано. Чтобы обойти это, вы можете либо использовать Array.prototype.reduce() (чтобы некоторые данные изменялись в ходе итераций), либо использовать рекурсивный подход.
Не связано: Array(maxRows).fill().map(callback)
можно заменить на Array.from({ length: maxRows }, callback)
@adiga: первый будет работать быстрее, если это имеет значение
@YevgenGorbunkov правда? Array.from
пропускает заполнение массива неопределенным битом. Вот и подумал, что может быть быстрее
@adiga: просто так: jsbench.me/i7kj2wjde2/1
@adiga: я полагаю, причина в том, что js-движок лучше оптимизирован для обработки массива известного размера, а не для создания этого на лету.
Поскольку Array.prototype.map()
не изменяет исходный массив на месте в режиме реального времени, а возвращает новый массив после того, как он завершит цикл по вашему исходному массиву, на самом деле нет смысла обращаться к triangle
- это все равно будет скудный массив из 5 элементов: [,,,,]
( возвращается Array().fill()
), пока .map()
-цикл не завершится.
Чтобы обойти это, вы можете либо придумать рекурсивный подход, либо использовать Array.prototype.reduce():
const maxRows = 5,
triangle = Array(maxRows)
.fill()
.reduce((acc, _, i) => {
const rowData = Array(i+1)
.fill()
.map((__,j) =>
!j || j == i
? 1
: acc[i-1][j-1] + acc[i-1][j]
)
acc.push(rowData)
return acc
}, [])
triangle.forEach(row => console.info(JSON.stringify(row)))
.as-console-wrapper{min-height:100%;}
@YevgenGorbunkov все значения не определены внутри