0

I need to assign assign each input their own id.

const sep = words.map((word, ind) => {
  return (
     <div key={ind} className="guess__word">
       {word.split("").map((letter, id) => {
         if (letter === " ") {
           return <SpaceBox key={id} letter={letter} />;
         } else {
           return <LetterBox key={id} id={id} letter={letter} />;
         }
      })}
     </div>
   );
 });

The problem that I am having is that due to the map being nested, the value of id keeps reseting back to 0. Each word of words has a different length so if kinda hard to figure out if there is a math equation that would help me solve this.

for reference, the length of each word is 10, 3, 4, and 4.

Also I need the ids to equal up to the length of words. So I would need the ids to be 0-20.

Troy
  • 5
  • 3
  • What you’re saying doesn’t make logical sense. You need an id per letter per word. But you’re saying you can’t have more ids than words. This is logically not possible. – bryan60 Apr 03 '22 at 01:06
  • Yes to that first part. I think you were misunderstanding me. I was considering the fact that count starts at 0 so it would still techincally add up to 21 ( the length of words (10 + 3 + 4 + 4 =21) ) – Troy Apr 03 '22 at 01:11

2 Answers2

1

if kinda hard to figure out if there is a math equation that would help me solve this.

There is - given indicies X and Y, you can map onto the Xth prime number raised to the Y power - but that's way overkill here. Just use string concatenation, for the key, eg indicies 3 and 4 can produce a key of 3_4.

I'd recommend not using .split('') to get a character array from a string - invoke the array's iterator instead, otherwise you'll occasionally run into problems when odd characters are present.

const sep = words.map((word, ind) => {
  return (
     <div key={ind} className="guess__word">
       {[...word].map((letter, id) => {
         const key = `${ind}_${id}`;
         if (letter === " ") {
           return <SpaceBox key={key} letter={letter} />;
         } else {
           return <LetterBox key={key} id={id} letter={letter} />;
         }
      })}
     </div>
   );
 });

If the words may change, you might want to use a slightly different key, to differentiate a SpaceBox letter from a LetterBox letter.

<LetterBox key={key + ' '} id={id} letter={letter} />

If you have to use only array indicies in order starting from 0, it'll be uglier - declare the last used number outside, and use and increment it inside the loop.

let lastId = -1;
const sep = words.map((word) => {
  return (
     <div key={ind} className="guess__word">
       {[...word].map((letter) => {
         if (letter === " ") {
           return <SpaceBox key={++lastId} letter={letter} />;
         } else {
           return <LetterBox key={++lastId} id={lastId} letter={letter} />;
         }
      })}
     </div>
   );
 });

Due to the odd key requirement, the above is only a good approach if the words are static. If they may change, memoize the boxes based on the words.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Hi, Thank you for super quick response. I updated my question but he had already answered before I could edit it. I need the ids to match the length of the words array(21). Is there a way to do that? I have a work around if not but it would be great if there was. – Troy Apr 03 '22 at 01:03
0

To save math, you might as well just concatenate the numbers in a meaningful way

const sep = words.map((word, ind) => {
  return (
     <div key={ind} className="guess__word">
       {word.split("").map((letter, id) => {
         const key = `${ind}-{key}`;
         if (letter === " ") {
           return <SpaceBox key={key} letter={letter} />;
         } else {
           return <LetterBox key={key} id={id} letter={letter} />;
         }
      })}
     </div>
   );
 });
Eric Webb
  • 361
  • 3
  • 10