skip to Main Content

I’m fairly new to React, so there is probably just an easier way to do this.

But I have a List of items

const NOTES = [
  { id: 0, val: "C" },
  { id: 1, val: "C#" },
  { id: 2, val: "D" },
  { id: 3, val: "D#" },
  { id: 4, val: "E" },
  { id: 5, val: "F" },
  { id: 6, val: "F#" },
  { id: 7, val: "G" },
  { id: 8, val: "G#" },
  { id: 9, val: "A" },
  { id: 10, val: "A#" },
  { id: 11, val: "B" },
];

The requirement is that a user will give a number of notes to display.
So for example, if the user gives 14 you would display

C, C#, D, D#, E, F, F#, G, G#, A, A#, B, C, C#

I currently have this

  const keys = [...Array(13).keys()];
  console.log("keys: ", keys);
  return (
    <div>
      {keys.map((item) => (
        <div key={item}>{NOTES[item].val}</div>
      ))}
    </div>
  );

But because there are only 12 elements in the List, I get an error. Is there any way to make it so that when it reaches the last element in the List, I go back to the first element and continue ‘n’ times?

4

Answers


  1. Chosen as BEST ANSWER

    In case anyone is stupid like me, Jurgen's solution is the way to go.

    I got errors in the past due to now giving a type for my array.

      var arr: string[] = [];
    

    So the full solution would be something like this

    var arr: string[] = [];
      var c = 2;
      for (var i = 0; i < numFrets; i++) {
        arr[i] = NOTES[c].val;
        c++;
        if (c == 12) {
          c = 0;
        }
      }
    
      return (
        <div>
          {arr.map((item) => (
            <div>{item}</div>
          ))}
        </div>
      );
    

  2. Instead of using keys.map

    You can create a function

    This function will receive a parameter (the number of times that you need notes in this example 14)

    Then inside the func declare the NOTES array

    Set a counter in 0 (let variable)

    Set an empty array that you are going to fill with info after

    Define a for loop that is going from 0 to the param that you defined

    Inside for do an array.push
    Example: myArray.push(NOTES[counter])

    Execute counter++
    If the counter is 11 set it to 0 again

    Then outside for loop return the array

    Then replace keys.map with myFunc(16).map

    And each item will be the array that are you looking for

    Hope this helps you to find the right solution

    Login or Signup to reply.
  3. You can use modulo to loop back to the start of the array:

    const NOTES = [{
        id: 0,
        val: "C"
      },
      {
        id: 1,
        val: "C#"
      },
      {
        id: 2,
        val: "D"
      },
      {
        id: 3,
        val: "D#"
      },
      {
        id: 4,
        val: "E"
      },
      {
        id: 5,
        val: "F"
      },
      {
        id: 6,
        val: "F#"
      },
      {
        id: 7,
        val: "G"
      },
      {
        id: 8,
        val: "G#"
      },
      {
        id: 9,
        val: "A"
      },
      {
        id: 10,
        val: "A#"
      },
      {
        id: 11,
        val: "B"
      }
    ];
    
    function getNoteSequence(numOfNotes) {
      numOfNotes = numOfNotes || 0;
    
      const totalNotesDefined = NOTES.length;
    
      const result = [];
      for (let currNote = 0; currNote < numOfNotes; currNote++) {
        result.push(NOTES[currNote % totalNotesDefined]);
      }
    
      return result;
    }
    
    function generateHTML() {
      const noteSequence = getNoteSequence(14);
    
      document
        .querySelector('#notes-container')
        .innerHTML = noteSequence
          .map((note) => `<div key="${ note.id }">${ note.val }</div>`)
          .join('');
    }
    
    generateHTML();
    <div id="notes-container"></div>
    Login or Signup to reply.
  4. As jurgen has already mentioned, the same thing has been done below:

    const NOTES = [
      { id: 0, val: "C" },
      { id: 1, val: "C#" },
      { id: 2, val: "D" },
      { id: 3, val: "D#" },
      { id: 4, val: "E" },
      { id: 5, val: "F" },
      { id: 6, val: "F#" },
      { id: 7, val: "G" },
      { id: 8, val: "G#" },
      { id: 9, val: "A" },
      { id: 10, val: "A#" },
      { id: 11, val: "B" },
    ];
    
    
    const userInput = 14;
    const keys = [...Array(13).keys()];
    console.log("keys: ", keys);
    
    
    const prepareFinalList = () => {
      const finalListEl = [];
      let userInputCounter = 0;
      let i = 0;
    
    // this userInput variable required to break the loop
      while(userInputCounter <= userInput) {
        if (i > NOTES.length - 1) {
          i = 0;
        }
    
        const item = NOTES[i];
    
        finalListEl[userInputCounter] = (<div key={item.id}>{item.val}</div>)
        
        i++;
        userInputCounter++;
      }
    
      // this will have the mapped dom structure
      return finalListEl;
    };
    
    
    return (
      <div>
        {/* 
        1. instead of using map you should use different loop. Maybe normal for loop or while loop 
           and prepared your own Dom's array.
    
        */}
        {prepareFinalList()}
      </div>
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search