0

Below I have defined an object and then created a 3x3 array with each element holding an instance of myObject. I'm expecting function removeNumberFromArray to iterate over each element and therefore each object and remove the number 32 from the array called myNumbers. My comments indicate what it actually logs to the console. The result is an empty array and I was expecting to have each object within the 9x9 array to have myNumbers array equal to [7,51,2,0,9].

I can't see where I am going wrong and I have tried breaking the problem down into smaller steps but splice seems to work, any ideas?

I'm using VS Code with Liveserver Extension with Firefox Browser.

const myObject = {
    myNumbers: [7,32,51,2,0,9],
    myName: "John",
    myLastName: undefined,
    age: 26
};

for (i = 0; i <= 2; i++) {
    for (j = 0; j <= 2; j++) {
        myArray[i][j] = Object.create(myObject);
    }
}

function removeNumberFromArray(numberToRemove) {
    myArray.forEach(ele => {
        ele.forEach(square => {
            let index = square.myNumbers.indexOf(numberToRemove);
            square.myNumbers.splice(index, 1);
        })
    });
}

console.log(myArray[0][0].myNumbers); //[7, 32, 51, 2, 0, 9]
removeNumberFromArray(32);
console.log(myArray[0][0].myNumbers);   //[]
btew2102
  • 73
  • 6
  • 1
    The code you included doesn't set `myArray` properly nor does it populate it correctly since `Object.create` sets the prototype. If you want to clone an object, [then use code actually designed for cloning](https://stackoverflow.com/a/728694/5923139). – Aplet123 Nov 22 '20 at 18:44
  • 1
    You get an empty array because you are calling `.splice()` with `-1` as the index at which you want to remove one element from. This is because `Object.create` is not for cloning an object. Instead of using `Object.create()`, clone `myObject` as `{ ...myObject, myNumbers: [ ...myObject.myNumbers ] };` – Yousaf Nov 22 '20 at 18:59

1 Answers1

2

By using Object.create(myObject) you are using prototypal inheritance to create an object that inherits from myObject, which is not what you're looking for. I suggest you to create a small "factory" function to generate unique objects like this:

const arrayLike = { length: 3 };
const myArray = Array.from(arrayLike, () => Array.from(arrayLike));

const objectFactory = () => ({
    myNumbers: [7, 32, 51, 2, 0, 9],
    myName: "John",
    myLastName: undefined,
    age: 26
});

for (i = 0; i <= 2; i++) {
    for (j = 0; j <= 2; j++) {
        myArray[i][j] = objectFactory();
    }
}

function removeNumberFromArray(numberToRemove) {
    myArray.forEach(ele => {
        ele.forEach(square => {
            let index = square.myNumbers.indexOf(numberToRemove);
            if(~index) square.myNumbers.splice(index, 1);
        })
    });
}

console.log(myArray[0][0].myNumbers); //[7, 32, 51, 2, 0, 9]
removeNumberFromArray(32);
console.log(myArray[0][0].myNumbers);   //[]
Guerric P
  • 30,447
  • 6
  • 48
  • 86
  • `.fill(new Array(3))` - this will fill the array with same array instead of a separate array at each index. I suggest to use `.map()`: `new Array(3).fill().map(() => new Array(3));`. – Yousaf Nov 22 '20 at 19:05
  • Thanks @Guerric. I presume: exmple 1. ``` const objectFactory = () => ({ myNumbers: [7, 32, 51, 2, 0, 9], myName: "John", myLastName: undefined, age: 26 }); ``` is the same as: example 2. ``` const objectFactory = () => { return { myNumbers: [7, 32, 51, 2, 0, 9], myName: "John", myLastName: undefined, age: 26 } }; ``` How does surrounding the object properties with parentheses remove the need for the return statement in example 2? – btew2102 Nov 23 '20 at 14:10
  • 1
    The surrounding parenthesis indicate that the curly braces represent an object, and not a function body. That means there is no function body, and the return statement is not needed in this case – Guerric P Nov 23 '20 at 14:19