incognitoCoder
incognitoCoder

Reputation: 3

Why is Reduce closing out before it finishes looping through the entire array that is passed in?

I am trying to loop through the given array and check that there are no repeated names. If there are, add a number next to the repeated file name. This is my code:

const renameFiles = (arr) => {
 let n = 1;
 return arr.reduce((accum, element) => {
  if (!accum.includes(element)) accum.push(element);
  else {
   element = `${element}(${n})`;
   n++;
   if (!accum.includes(element)) accum.push(element);
  }

 return accum;
 }, []);
}

When given:

renameFiles([
    'a(1)',
    'a(6)',
    'a',
    'a',
    'a',
    'a',
    'a',
    'a',
    'a',
    'a',
    'a',
    'a',
  ]);

I only get

[ 'a(1)', 'a(6)', 'a', 'a(2)', 'a(3)', 'a(4)', 'a(5)', 'a(7)', 'a(8)', 'a(9)' ]

instead of:

[ 'a(1)', 'a(6)', 'a', 'a(2)', 'a(3)', 'a(4)', 'a(5)', 'a(7)', 'a(8)', 'a(9)', 'a(10)', 'a(11)' ].

I am not sure why it is not finishing looping through the last two elements in the array.

Upvotes: 0

Views: 36

Answers (1)

Bergi
Bergi

Reputation: 665344

If an element with the added number is still found in the accum, you just drop it instead of trying again with an incremented number. So the two as that would have been converted to a(1) and a(6) are removed from the output. You can use

function renameFiles(arr) {
  let n = 1;
  return arr.reduce((accum, element) => {
    let suffix = "";
    while (accum.includes(element+suffix)) {
      suffix = "(" + n + ")";
      n++;
    }
    accum.push(element+suffix);
    return accum;
  }, []);
}

Upvotes: 1

Related Questions