3

I'm trying to create a function to create pascals triangle in javascript with Array.map() function.

Actually, i'm using this function :

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.log(triangle)

But I would like to use something like this :

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];
  });
});

Is there a way to access triangle variable inside the second Array.map() ?

adiga
  • 34,372
  • 9
  • 61
  • 83
Thomas
  • 88
  • 7
  • @YevgenGorbunkov all values are undefined inside – Thomas Dec 24 '20 at 13:32
  • 2
    Just figured out that it won't work for your code, since what you get with `Array(maxRows).fill()` is array of `undefined`'s. `.map()` does not actually mutate your `triangle` variable in-place, it returns **new array** once it's done. To get around this, you may either use [`Array.prototype.reduce()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) (to have some data mutated over the iterations), or use recursive approach. – Yevhen Horbunkov Dec 24 '20 at 13:34
  • 1
    Unrelated: `Array(maxRows).fill().map(callback)` can be replaced with `Array.from({ length: maxRows }, callback)` – adiga Dec 24 '20 at 13:38
  • @adiga: the former would perform faster, if that matters – Yevhen Horbunkov Dec 24 '20 at 13:40
  • 1
    @YevgenGorbunkov really? `Array.from` skips the filling the array with undefined bit. So, thought it might be faster – adiga Dec 24 '20 at 13:41
  • @adiga: just for fun: https://jsbench.me/i7kj2wjde2/1 – Yevhen Horbunkov Dec 24 '20 at 13:49
  • 1
    @adiga: I believe, the reason is that js-engine is way better optimized treating array of the know size, rather than building that on-the-fly – Yevhen Horbunkov Dec 24 '20 at 13:50

1 Answers1

1

Since Array.prototype.map() does not mutate source array in-place in real-time, but rather returns new array once it's done looping through your source array, there's actually no point of accessing triangle - it will still be a scarce array of 5 items: [,,,,] (returned by Array().fill()), until the .map()-loop is over.

To get around this, you may either come up with recursive approach, or use 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.log(JSON.stringify(row)))
.as-console-wrapper{min-height:100%;}
Yevhen Horbunkov
  • 14,965
  • 3
  • 20
  • 42