Rey
Rey

Reputation: 1433

Problem With Conditional Check When Two Elements of Array are Same String Value

I am running into a problem where, if two elements of an array are the same string value, then it produces problems in what gets printed to the console based on my current conditional logic, that looks like this:

const homeTeamScorers = ['John Smith', 'John Smith', 'Sam Jones'];
const homeTeamGoalTimes = [3, 10, 22];  

 for (let t of homeTeamGoalTimes) {
  const timeIdx = homeTeamGoalTimes.indexOf(t);
  for (let homeScorer of homeTeamScorers) {
    const scorerIdx = homeTeamScorers.indexOf(homeScorer);
    if (scorerIdx === timeIdx) {
      console.log('home scorerIdx:', scorerIdx);
      console.log('home goalTime: ', t);
      console.log('home timeIdx:', timeIdx);
      console.log('home scorer: ', homeScorer);
      console.log('-----------');
    }
  }
 }

This is what I see in the console (notice the second element group is repeating the first):

home scorerIdx: 0
home goalTime:  3
home timeIdx: 0
home scorer:  John Smith
-----------
home scorerIdx: 0
home goalTime:  3
home timeIdx: 0
home scorer:  John Smith
-----------
home scorerIdx: 2
home goalTime:  22
home timeIdx: 2
home scorer:  Sam Jones
-----------

When what I want to see is this:

home scorerIdx: 0
home goalTime:  3
home timeIdx: 0
home scorer:  John Smith
-----------
home scorerIdx: 1
home goalTime:  10
home timeIdx: 1
home scorer:  John Smith
-----------
home scorerIdx: 2
home goalTime:  22
home timeIdx: 2
home scorer:  Sam Jones
-----------
                        

What am I missing here?

Upvotes: 2

Views: 46

Answers (2)

machineghost
machineghost

Reputation: 35813

Your issue has nothing to do with your code, and everything to do with your data. That data has two 'John Smith' in it, which means this line:

const scorerIdx = homeTeamScorers.indexOf(homeScorer);

will be 0 for both the first AND second 'John Smith'.

One way to fix this would be by using objects with ID properties to represent your players. You could change your home team scorers variable to:

const homeTeamScorers = [
    { id: 1, name: 'John Smith'},
    { id: 2, name: 'John Smith'},
    { id: 3, name: 'Sam Jones'}
];

and then use the ID for all your indexing. However, really I don't think you need two indexes at all (ie. one for the score and one for the team member), and I think that's you real issue.

If you change:

for (let t of homeTeamGoalTimes) {
  const timeIdx = homeTeamGoalTimes.indexOf(t);
  for (let homeScorer of homeTeamScorers) {
    const scorerIdx = homeTeamScorers.indexOf(homeScorer);
    if (scorerIdx === timeIdx) {
      // do log

to:

for (let index of homeTeamGoalTimes) {
  // do log, and use index for both timeIdx and scorerIdx

That should simplify your code and fix your problem. This should work because both your arrays:

const homeTeamScorers = ['John Smith', 'John Smith', 'Sam Jones'];
const homeTeamGoalTimes = [3, 10, 22];  

Have the same (conceptual) index: in both cases the index represents the index of the score in the game (in the first array it's "who scored that index of goal" and in the second it's "when was the score of that index of goal"). Thus, there's really no need to indexOf at all.

P.S. How I'd really recommend doing it though would be ...

const homeTeamScores = [
  { scorer: 'John Smith', time: 3 },
  // ...

because that way your two bits of data for each score are inherently linked in an object, instead of you the coder having to "link" them via index.

Upvotes: 1

Moshe Sommers
Moshe Sommers

Reputation: 1516

const timeIdx = homeTeamGoalTimes.indexOf('John Smith');

Will always return the first instance of John Smith. I would suggest using foreach where you can access the actual index of the element in the loop.

homeTeamGoalTimes.foreach((el, index) => {
   const timeIdx = index;
})

Upvotes: 1

Related Questions