p5.js icon indicating copy to clipboard operation
p5.js copied to clipboard

Array.fill() didn't fill; it fill color.

Open MrBean3737 opened this issue 3 years ago • 4 comments

Most appropriate sub-area of p5.js?

  • [ ] Accessibility (Web Accessibility)
  • [ ] Build tools and processes
  • [x] Color
  • [ ] Core/Environment/Rendering
  • [ ] Data
  • [ ] DOM
  • [ ] Events
  • [ ] Friendly error system
  • [ ] Image
  • [ ] IO (Input/Output)
  • [ ] Localization
  • [ ] Math
  • [ ] Unit Testing
  • [ ] Typography
  • [ ] Utilities
  • [ ] WebGL
  • [ ] Other (specify if possible)

Details about the bug:

  • p5.js version: 1.4.0
  • Web browser and version: 92.0.4515.107 (Official Build) (64-bit)
  • Operating System: Windows 10 Version 10.0.19042 (Build 19042)
  • Steps to reproduce this:
var Test = Array(10).fill(Array(10))

function setup() {
  createCanvas(400, 400);
  for(var x=0;x<Test.length;x++){
    for(var y=0;y<Test[x].length;y++){
      console.log(Test[x][y])
    }
  }
}

function draw() {
}

Console:

(100) undefined

MrBean3737 avatar Jul 27 '21 21:07 MrBean3737

Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, be sure to follow the issue template if you haven't already.

welcome[bot] avatar Jul 27 '21 21:07 welcome[bot]

Hey @fgbhnjtgfvgtyhujikjuhygtfrdesw can you elaborate your issue properly. I tried to reproduce the issue but can't understand what you mean by it fills color.

As the code represents it fills 10 arrays with 10 empty arrays each that's why it showing 100 undefined.

malviys avatar Jul 28 '21 18:07 malviys

Try using

var Test = Array(10).fill(Array(10).fill(color('hex-value')));

malviys avatar Jul 28 '21 18:07 malviys

Hey, @MrBean3737! 👋

May I ask you what was the output you were expecting to see?

English is not my first language so I might be projecting my own struggles but I think there might be a misunderstanding about fill as in "fill my shapes with this color" and fill as in "fill this array with a value".

murilopolese avatar Jul 16 '22 15:07 murilopolese

Try using

var Test = Array(10).fill(Array(10).fill(color('hex-value')));

This is the right idea, but be careful because the .fill() value is 10 references to a single array rather than 10 arrays as you may intend. Changing an element of one will reflect across all 10 referenced copies of the same array.

I suggest avoiding fill in favor of spread syntax and .map:

const test = [...Array(10)].map(() => [...Array(10)].map(() => color("red")));

(Array(size).fill().map() would work too, but I find the .fill() to be easy to mess up--it only avoids aliasing on primitives)

Full p5 example:

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js"></script>
</head>
<body>
<script>

let colors;
let size;

function setup() {
  createCanvas(500, 500);
  noLoop();
  noStroke();
  const amount = 10;
  size = width / amount;

  colors = [...Array(amount)].map(() =>
    [...Array(amount)].map(() =>
      color(random(256), random(256), random(256))
    )
  );
  // won't work--gives one solid color:
  //colors = [...Array(amount)].fill(
  //  [...Array(amount)].fill(
  //    color(random(256), random(256), random(256))
  //  )
  //);
}

function draw() {
  colors.forEach((row, i) => {
    row.forEach((color, j) => {
      fill(color);
      rect(i * size, j * size, size, size);
    });
  });
}

</script>
</body>
</html>

If that syntax is confusing, here's a function you can treat as a black box/library routine that does the job:

const fillArray = (length, filler) =>
  [...Array(length)].map((_, i) =>
    typeof filler === "function" ? filler(i) : filler
  )
;

// test it:
console.log(fillArray(3)); // => [undefined, undefined, undefined]
console.log(fillArray(3, "foo")); // => ["foo", "foo", "foo"]
console.log(fillArray(4, i => i * 2)); // => [0, 2, 4, 8]
console.log(fillArray(3, i => fillArray(2, j => i * 2 + j))); // => [[0, 1], [2, 3], [4, 5]]

// or use it in the above code:
colors = fillArray(amount, () =>
  fillArray(amount, () =>
    color(random(256), random(256), random(256))
  )
);

Note that Array#fill from plain JavaScript and fill() from p5.js are totally different functions with similar names.

ggorlen avatar Sep 01 '22 19:09 ggorlen