Search code examples
javascriptarraysloopsiterationfill

Simplifying a two-dimensional array creation with the fill() method in JavaScript


const hole = 'O'; // Declare constant for the hole character
const fieldCharacter = '░'; // Declare constant for the field character

// Initialize a field with a given height, width, and percentage of holes
function initiliazeField(height, width, percentage) {
    // Return either the hole or field character based on the percentage
    // If the percentage is not between 0 and 35, log an error message
    const fieldOrHole = (percentage) => {
        return percentage >= 0 && percentage <= 35 ?
            Math.floor(Math.random() * 35) < percentage ?
            hole :
            fieldCharacter :
            console.log('Please enter a number between 0 - 35');
    }

    // Initialize an empty array to hold the rows of the field
    const rows = [];
    // Create rows for the field
    for (let i = 0; i < height; i++) {
        // Initialize an empty array to hold the characters in the row
        const row = [];
        // Populate the row with the appropriate character based on the percentage
        for (let j = 0; j < width; j++) {
            row.push(fieldOrHole(percentage));
        }
        // Add the row to the field
        rows.push(row);
    }
    // Map each element in the rows array to a new array, and log each row to the console
    return rows.map(subArray => subArray.map(element => element)).forEach(row => console.log(row.join(' ')));
};

// Print the initialized field to the console
console.log(initiliazeField(20, 20, 20));

Output:

// Expected a randomly generated two-dimensional array

░ ░ ░ O O ░ O ░ O O
O O O ░ ░ O O ░ ░ O
░ O ░ ░ O ░ O O O O
O O O ░ O ░ ░ O ░ O
░ O O ░ O ░ O ░ ░ O
░ ░ ░ O O ░ O O O ░
O ░ ░ ░ O ░ O ░ ░ ░
O O O ░ ░ ░ O O ░ O
O ░ ░ O ░ ░ ░ ░ O ░
O O ░ ░ ░ ░ O O ░ O

This code is defining a function initiliazeField() that generates a two-dimensional array representing a field with a given height, width, and percentage of holes. The field is represented as an array of rows, with each row being an array of characters. The characters are either a hole ('O') or a field character ('░').

The function takes three parameters:

  • height: the field's height, represented as the number of rows in the field.

  • width: the width of the field, represented as the number of columns in the field.

  • percentage: the percentage of holes in the field (must be a number between 0 and 35) The function first defines a nested function fieldOrHole() that returns either the hole or field character based on the given percentage. If the percentage is not between 0 and 35, an error message is logged to the console.

The function then initializes an empty array of rows to hold the rows of the field. It creates rows for the field by iterating over a loop and using the height parameter to determine the number of rows. Within the loop, it initializes an empty array row to hold the characters in the row, and populates the row with characters using a nested loop. The width parameter is used to determine the number of columns in the row. The character for each position is determined by calling the fieldOrHole() function.

Finally, the function maps each element in the rows array to a new array and logs each row to the console using the forEach() method. The map() and forEach() methods are used to iterate over the rows array and log each row to the console. The join(' ') method is used to concatenate the elements in the row with a space character, so the output is formatted correctly.

How can the initiliazeField() function be simplified using the fill() method?


Solution

  • As already stated by @rajesh in the commentary, .fill fills the entire array with same value. To create arrays with different values, defined by the result of a function call, you would probably want to use Array.from:

    const gen = (height, width, percentage) => Array.from(
      {length: height}, 
      () => Array.from(
        {length: width}, 
        () => Math.random()*100 < percentage ? '0' : '░'
      )
    );
    
    const A = gen(7, 10, 20);
    console.log(A.map(a => a.join('')).join("\n"));

    I excluded the I/O part since it makes sense to separate it from the code generating the matrix