skip to Main Content

The idea is to loop across the diceValues array and within each single iteration, store the current item in loop into an outside array named "firstSplitDiceValues". The codeblock below is a much simplified form to outline the challenge.

So in other words, every iteration should keep building the length of the firstSplitDiceValues and at the same time this firstSplitDiceValues should be pushed as value in another array named "moves".

let firstSplitDiceValues = [];
const tokens = ['A', 'B', 'C', 'D'];
const diceValues = [1, 3, 4, 6];
const moves = [];

for (let diceValue=0; diceValue < diceValues.length; diceValue++) {
    firstSplitDiceValues[diceValue] = diceValues[diceValue];  // [1]
     
    moves.push([
       {
           [tokens[diceValue]]: firstSplitDiceValues
       }
    ]);
}
console.log(moves);

// What I expect:
// Moves array should contain:
[
    [{"A": [1]}],
    [{"B": [1, 3]}],
    [{"C": [1, 3, 4]}],
    [{"D": [1, 3, 4, 6]}]
]

// Actual results:
// Moves array only shows final expected value on all iterations
[
    [{"A": [1, 3, 4, 6]}],
    [{"B": [1, 3, 4, 6]}],
    [{"C": [1, 3, 4, 6]}],
    [{"D": [1, 3, 4, 6]}]
]

// What I expect:
// Moves array should contain:

[
    [{"A": [1]}],
    [{"B": [1, 3]}],
    [{"C": [1, 3, 4]}],
    [{"D": [1, 3, 4, 6]}]
]

3

Answers


  1. You’re pushing the same array firstSplitDiceValues in memory to moves for each iteration. Instead you want to create a new array for each move and populate it with appropriate values. You can use slice() to achieve the result. Here is the updated code.

    const firstSplitDiceValues = [];
    const tokens = ['A', 'B', 'C', 'D'];
    const diceValues = [1, 3, 4, 6];
    const moves = [];
    
    for (let diceValue = 0; diceValue < diceValues.length; diceValue++) {
        const splitDiceValues = diceValues.slice(); // Create a shallow copy of diceValues
        const token = tokens[diceValue];
        splitDiceValues.splice(diceValue, 1); // Remove the current dice value from splitDiceValues
        moves.push([{ [token]: splitDiceValues }]);
    }
    
    console.log(moves);

    I hope this solves your problem

    Login or Signup to reply.
  2. As you only ever create on firstSplitDiceValues array when your program initially starts, that means that there’s only one firstSplitDiceValues array in memory. As a result, when you change this array at each iteration, you’re really changing the same array in memory, and so the array you pushed previously will also update. To get your expected result, the easiest thing to do would be to create a new array at each iteration. That way you’re creating a unique array in memory for each iteration and so it won’t impact the other references you’ve pushed into moves already. The easiest way to create an array holding n items from diceValues is to use diceValues.slice(0, n), which gives you the first n items from diceValues as a new array. With this approach, you don’t need firstSplitDiceValues anymore:

    const tokens = ['A', 'B', 'C', 'D'];
    const diceValues = [1, 3, 4, 6];
    const moves = [];
    
    for (let i = 0; i < diceValues.length; i++) {
        const diceValuesSubset = diceValues.slice(0, i + 1);
         
        moves.push([
           {
               [tokens[i]]: diceValuesSubset
           }
        ]);
    }
    console.log(moves);

    This can be written more declaratively with .map():

    const tokens = ['A', 'B', 'C', 'D'];
    const diceValues = [1, 3, 4, 6];
    const moves = diceValues.map((_, i) => ({
      [tokens[i]]: diceValues.slice(0, i + 1)
    }));
    console.log(moves);

    If you need to update firstSplitDiceValues, then I would suggest you .push() to it each iteration, and then call .slice() on it to get a make a unique copy in memory to avoid changing that version of the array on subsequent iterations:

    const firstSplitDiceValues = [];
    const tokens = ['A', 'B', 'C', 'D'];
    const diceValues = [1, 3, 4, 6];
    const moves = [];
    
    for (let i = 0; i < diceValues.length; i++) {
      firstSplitDiceValues.push(diceValues[i]);
      moves.push([
        {
          [tokens[i]]: firstSplitDiceValues.slice()
        }
      ]);
    }
    console.log(moves);
    console.log(firstSplitDiceValues); // same as values as diceValues
    Login or Signup to reply.
  3. Arrays (and objects) are not copied when you assign them to another variable, or to an object’s property. Instead the variable/property points to the original array. Because you mutate the firstSplitDiceValues array by assigning a new value firstSplitDiceValues[diceValue] = diceValues[diceValue];, the original array, and everything that points to it would show all the values.

    Use Array.map() to iterate tokens, and slice the diceValues according to the current index (i). Slicing an array creates a new array.

    const tokens = ['A', 'B', 'C', 'D'];
    const diceValues = [1, 3, 4, 6];
    
    const moves = tokens.map((t, i) => ({ [t]: diceValues.slice(0, i + 1) }));
    
    console.log(moves);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search