0

I have a huge array of strings, here is a small portion of it:

let x = [
  'FireDisaster_03_', 
  'FireDisaster_03_', 
  'FireDisaster_03_', 
  'FireDisaster_05_', 
  'FireDisaster_05_', 
  'FireDisaster_07_', 
  'FireDisaster_07_', 
  'FireDisaster_07_', 
  'FireDisaster_07_', 
  'FireDisaster_08_', 
  'FireDisaster_08_', 
  'FireDisaster_08_'
] 

I need to add sequential number to each duplicate string. Such that the result will look like:

[
  'FireDisaster_03_0', 
  'FireDisaster_03_1',  
  'FireDisaster_03_2', 
  'FireDisaster_05_0', 
  'FireDisaster_05_1', 
  'FireDisaster_07_0', 
  'FireDisaster_07_1', 
  'FireDisaster_07_2', 
  'FireDisaster_07_3', 
  'FireDisaster_08_0', 
  'FireDisaster_08_1', 
  'FireDisaster_08_2'
]

Please help me solve this

Thank you

2
  • 1
    And what are using to do this? Commented Apr 28, 2020 at 16:40
  • Well, its more machine learning purposes, there are many image files but they are not named properly, I was able to bring it up to what I have now but was unable to add a number for repeated names Commented Apr 29, 2020 at 8:01

4 Answers 4

3

You could take a object for the seen values and store the counter.

This approach uses a closure over seen with an IIFE (immediately-invoked function expression) and an expression which checks if the key exits in the object or not.

In the first case, it takes the value from the property and adds one; in the second case it takes zero as value for assigning to the property and at the same time this value is used to concat with the string.

let x = ['FireDisaster_03_', 'FireDisaster_03_', 'FireDisaster_03_', 'FireDisaster_05_', 'FireDisaster_05_', 'FireDisaster_07_', 'FireDisaster_07_', 'FireDisaster_07_', 'FireDisaster_07_', 'FireDisaster_08_', 'FireDisaster_08_', 'FireDisaster_08_'],
    result = x.map(
        (seen => v => v + (seen[v] = v in seen ? seen[v] + 1 : 0))
        ({})
    );

console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

1

You can use reduce. Also sorting the array before operation to compare only with previous element

let x = ['FireDisaster_03_', 'FireDisaster_03_', 'FireDisaster_03_', 'FireDisaster_05_', 'FireDisaster_05_', 'FireDisaster_07_', 'FireDisaster_07_', 'FireDisaster_07_', 'FireDisaster_07_', 'FireDisaster_08_', 'FireDisaster_08_', 'FireDisaster_08_'].sort();
let newStrArray = x.reduce((accumulator, currentVal, index) => {
  // for the first element of the array no changes need to be done
  if (index === 0) {
    accumulator.push(`${currentVal}${index}`);
  } else {
    // check if the current element is same as the previous element from
    // the main array
    const prevVal = x[index - 1];
    if (prevVal === currentVal) {
      // if same then get the previous element from accumulator array
      const getPrevVal = accumulator[index - 1];
      // get the last character , convert to number and increase it by 1
      const num = parseInt(getPrevVal.charAt(getPrevVal.length - 1), 10) + 1;
      // push value to accumulator array
      accumulator.push(`${currentVal}${num}`)
    } else {
      // if previous and current element are not same then 
      // push current element in accumulator array
      accumulator.push(`${currentVal}0`)
    }
  }


  return accumulator;
}, []);
console.log(newStrArray)

Comments

1

You can use a recursive function and .map() like this:

let x = ['FireDisaster_03_', 'FireDisaster_03_', 'FireDisaster_03_', 'FireDisaster_05_', 'FireDisaster_05_', 'FireDisaster_07_', 'FireDisaster_07_', 'FireDisaster_07_', 'FireDisaster_07_', 'FireDisaster_08_', 'FireDisaster_08_', 'FireDisaster_08_']

x = x.map((c, i, a) =>
  a.indexOf(c) === i ? c + '0' : f(a.indexOf(c), c, i, a.slice(1), 1)
);

function f(ac, c, i, a, s) {
  return a.indexOf(c) === i - s ? c + (s - ac) : f(ac, c, i, a.slice(1), s + 1);
}

console.log(x);

Comments

1
found = {}
x.forEach( (val, i) => {
    found[val] = (found[val]||0) +1;
    x[i] += found[val]-1;
})

If you don't mind starting with 1, can remove last -1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.