Найти дубликаты строк в массиве и изменить их - PullRequest
0 голосов
/ 28 апреля 2020

У меня огромный массив строк, вот небольшая его часть:

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_'
] 

Мне нужно добавить порядковый номер для каждой дублирующейся строки. Так что результат будет выглядеть так:

[
  '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'
]

Пожалуйста, помогите мне решить эту проблему

Спасибо

Ответы [ 4 ]

3 голосов
/ 28 апреля 2020

Вы можете взять объект для видимых значений и сохранить счетчик.

В этом подходе используется замыкание свыше seen с IIFE ( выражением немедленного вызова функции ) и выражение, которое проверяет, находится ли ключ в объекте или нет.

В первом случае он берет значение из свойства и добавляет единицу; во втором случае для присвоения свойству в качестве значения берется ноль, и в то же время это значение используется для сопоставления со строкой.

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);
1 голос
/ 28 апреля 2020

Вы можете использовать reduce. Также сортируем массив перед операцией для сравнения только с предыдущим элементом

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)
1 голос
/ 28 апреля 2020
found = {}
x.forEach( (val, i) => {
    found[val] = (found[val]||0) +1;
    x[i] += found[val]-1;
})

Если вы не возражаете, начиная с 1, можете удалить последний -1

1 голос
/ 28 апреля 2020

Вы можете использовать рекурсивную функцию и .map(), например:

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);
...