Home > Mobile >  How to loop through an array starting at an index in JS
How to loop through an array starting at an index in JS

Time:01-09

How would one go about looping through this array to get every second "note" starting at the note of choice eg start at F and get f,a,c. Any help would be greatly appricated :)

let notes = ['c','d','e','f','g','a','b'];

CodePudding user response:

You can use findIndex and filter using remainder operator

I assume you want to wrap around

If I wrap I get f,a,c,e If not I get f,a, so I assume your expected output was missing the e ?

let notes = ['c', 'd', 'e', 'f', 'g', 'a', 'b'];

const findNotes = (startNote,gap) => {
  const start = notes.findIndex(note => note === startNote)
  if (start !=-1) return notes.slice(start).concat(notes.slice(0,start)).filter((note,i) => i%gap===0)
  return "not found"
};
console.log(findNotes("f",2))

CodePudding user response:

You can use a for loop and start the loop at the index of the element you want to start at. For example this will output: 'f', 'a'.

let notes = ['c', 'd', 'e', 'f', 'g', 'a', 'b'];

let startIndex = 3; // start at 'f'

for (let i = startIndex; i < notes.length; i  = 2) {
  let note = notes[i];
  console.log(note);
}

CodePudding user response:

If this is an operation that you repeat often, you can map each note with its index. Then create an array with 2 copies of notes to easily get next values in a circular manner.

let notes = ['c', 'd', 'e', 'f', 'g', 'a', 'b'],
    indexMap = notes.reduce((map, n, i) => map.set(n, i), new Map),
    twoNotes = [...notes, ...notes]

Then, create a function which gets the initial index from the mapper. And then items at the next 2 indices

function findNext(note) {
  const index = indexMap.get(note)
  return [ twoNotes[index], twoNotes[index 2], twoNotes[index 4] ]
}

or, if you want more indices in the future, you can make it generic one and get the indices array as an argument.

function findNext(note) {
  const index = notesIndex.get(note)
  return [0, 2, 4].map(i => twoNotes[i   index])
}

let notes = ['c', 'd', 'e', 'f', 'g', 'a', 'b'],
    indexMap = notes.reduce((map, n, i) => map.set(n, i), new Map),
    twoNotes = [...notes, ...notes]

function findNext(note) {
  const index = indexMap.get(note)
  return [0, 2, 4].map(i => twoNotes[i   index])
}

console.log(...findNext('f'))
console.log(...findNext('c'))

CodePudding user response:

You can use the modulo operator so that your index variable wraps around to 0 once it reaches the length of the notes array:

let notes = ['c','d','e','f','g','a','b'];
let startIndex = notes.indexOf('f');
for (let i = startIndex; i !==  startIndex-1; i = (i   2) % notes.length)) {
     console.log(notes[i]);
}

There is another super performant way using the for loop in some cases...

let notes = ['c','d','e','f','g','a','b'];
let startIndex = notes.indexOf('f')-2;
for (
     let i = startIndex;
     i !==  startIndex-1;
     (i = (i   2) % notes.length)==console.log(notes[i])
);

Note: the ; is very important after the for loop without {}.

Another method would be to slice the two parts of the array into the proper order first:

let notes = ['c','d','e','f','g','a','b'];
let startIndex = notes.indexOf('f');
notes = [
    ...notes.slice(startIndex),
    ...notes.slice(0, startIndex)
];

for (let i = 0; i < notes.length - 2; i  = 2) {
      let note = notes[i];
      console.log(note);
}
  • Related