Home > Blockchain >  Assign Nested map unique key, javascrpit
Assign Nested map unique key, javascrpit

Time:04-03

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.

CodePudding user response:

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.

CodePudding user response:

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>
   );
 });
  • Related