BeingPool
BeingPool

Reputation: 61

Looping through an array (`Object.keys(obj)`) to find a value

I'm learning Javascript, so pardon any mistakes in how I phrase the question.

I am writing a chess program to practice and learn. Currently, I am trying to write a function to find the color of a piece with the position as the parameter. The relevant pieces of code are as follows. The first two work as they were designed to, but the last does not.

let allPieces = board.getElementsByClassName('piece');

This sets allPieces as an object with the key values the html elemnts representing each piece, both black and white.

const getPiecePosition = function(element) {
  let position = window.getComputedStyle(element).getPropertyValue('grid-row-start');
  let letterIndex = alphabet.findIndex(function(letter) {
    return letter === position[0];
  });
  letterIndex += 1;
  return [letterIndex, Number(position[1])];
}

This takes a parameter in the form of the allPieces object with a specific key and returns the position as an array with the column number first and the row number second. ex. [2,3].

const getPieceByPosition = function(position) {
  let pce = Object.keys(allPieces).forEach(function(piece) {
    if (getPiecePosition(allPieces[piece]) == position) {
      return allPieces[piece].borderColor;
    }
  })
  return pce;
}

This is the function I am having trouble with. The idea behind it is that it will take each key in the allPieces object and loop through them using forEach() into the getPiecePosition() function to compare it with the position entered as the parameter. Since only one piece can inhabit any tile at once, it should never return multiple values.

I honestly don't know where to start debugging this code, but I have been trying for about an hour. It always just returns undefined instead of a truthy value of any kind.

Upvotes: 1

Views: 96

Answers (2)

Nick Parsons
Nick Parsons

Reputation: 50749

Your last function has a few issues:

  1. getPiecePosition(allPieces[piece]) == position
    

    Assuming position is an array, you're trying to compare an array with an array here using ==. However, since the two arrays are different references in memory, this will always give false, even if they contain the same elements:

    console.log([2, 3] == [2, 3]); // false

  2. You're trying to return from the callback of .forEach(). This won't achieve what you want, as return will jump out of the .forEach callback function, not your outer getPieceByPosition() function. This leads me to your final issue:

  3. The .forEach() method doesn't return anything. That is, it doesn't evaluate to a value once it is called. This means that let pce will always be undefined since you're trying to set it to the return value of .forEach(). This, in contrast to let letterIndex, is different, as letterIndex is set to the return value of .findIndex(), which does have a return value and is determined by the function you pass it.

One additional thing you can fix up is the use of Object.keys(allPieces). While this works, it's not the best approach for looping over your elements. Ideally, you would be able to do allPieces.forEach() to loop over all your elements. However, since allPieces is a HTMLCollection, you won't be able to do that. Instead, you can use a regular for loop or a for..of loop to loop over the values in your HTMLCollection.

Alternatively, there is a way to make allPieces.forEach() work. Instead of using board.getElementsByClassName('piece');, you can use the method .querySelectorAll('.piece'), which will give you a NodeList. Unlike a HTMLCollection, a NodeList allows you to use .forEach() on it to loop through its elements.

Upvotes: 1

HW Siew
HW Siew

Reputation: 1003

The return type of getElementsByClassName HTMLCollection Object. You should't use Object.keys to loop through each of 'piece' element. Insted, use the follow.

for(var i = 0 ; i < allPieces.length ; i++){
    var piece = allPieces[i];
    ... // and, do whatever with the getPiecePosition(piece)
}

Upvotes: 0

Related Questions