посмотрите, существует ли значение в нескольких массивах, измените значение в одном массиве, если оно есть - PullRequest
2 голосов
/ 15 февраля 2020

Скажите, что у меня были следующие два массива:

var arrToChangeAndCompare = [{name:'Bob'},{name:'Joe'},{name:'Alise'},{name:'Joe1'}];
var arrToCompare = [{name:'Frank'},{name:'Joe'},{name:'Jen'},{name:'Joe1'}];

И я хочу, чтобы первый массив содержал только уникальные имена в массиве, в который он входит, но также уникальные имена по сравнению со вторым массивом (arrToCompare). Чтобы было ясно, я не хочу УДАЛИТЬ значения, которые не являются уникальными, я хочу ИЗМЕНИТЬ их в «arrToChangeAndCompare», чтобы они были уникальными для обоих массивов. Имейте в виду, что если в arrToCompare есть неуникальные значения, это не имеет значения. Единственное правило заключается в том, что «arrToChangeAndCompare» имеет только уникальные имена в своем массиве, а также уникальные имена по сравнению с «arrToCompare».

У меня есть следующий код, который почти выполняет то, что я хочу, но он не Не проверяйте второй массив еще раз, когда он меняет значение в первом массиве на уникальное, в результате чего массив «arr» будет иметь все уникальные значения, но значения «arr» не являются уникальными в обоих массивах (Joe1 существует в первый массив и второй массив).

ПОЧТИ РАБОЧИЙ КОД

var arr = [{name:'Bob'},{name:'Joe'},{name:'Alise'},{name:'Joe1'}];
var arr2 = [{name:'Frank'},{name:'Joe'},{name:'Jen'},{name:'Joe1'}];

var arr3;
arr2.forEach(e2 => {
    arr3 = arr.map(e => {
        var name = e.name.match(/[a-zA-Z]*/)[0]
        if (e2.name === name) {
            var number = e.name.match(/[0-9]+/)
            if (number) {
                e.name = name + (+number[0] + 1)
            } else {
                e.name = name + 1
            }
        }
        return e 
    })
})
console.log(arr3)

Ожидаемый вывод массивов, перечисленных вверху, будет один массив, который выглядит следующим образом:

[
  {
    "name": "Bob"
  },
  {
    "name": "Joe2"
  },
  {
    "name": "Alise"
  },
  {
    "name": "Joe3"
  }
]

ОБЪЯСНЕНИЕ ВЫХОДА

  1. Боб уникален, поэтому для первого объекта в arrToChangeAndCompare фактическое не выполняется
  2. Джо не уникален по сравнению с arrtoCompare, поэтому его номер необходимо изменить. Но, поскольку Joe1 существует и в arrToChangeAndCompare, его необходимо снова увеличить до Joe2
  3. Alise уникален для обоих массивов, поэтому для третьего объекта в arrToChangeAndCompare
  4. Все значения в arrToChangeAndCompare являются теперь уникален по сравнению со своим собственным массивом и arrtoCompare

Пожалуйста, задавайте дополнительные вопросы по мере необходимости. Ваша помощь очень ценится!

1 Ответ

1 голос
/ 15 февраля 2020

Вы можете взять Set с name и буквенные части name и проверить на.

Если не найдено, добавьте строку для установки и возврата значения.

Если найдено, взять буквы, цифры и увеличивать числовое значение до тех пор, пока в наборе не останется больше объединенной строки. Затем обновите набор и верните новую строку.

var array1 = [{ name: 'Bob', foo: 42 }, { name: 'Bob', bar: 42 }, { name: 'Bob' }, { name: 'Joe' }, { name: 'Joe' }, { name: 'Joe' }, { name: 'Alise' }, { name: 'Joe1' }],
    array2 = [{ name: 'Frank' }, { name: 'Joe' }, { name: 'Jen' }, { name: 'Joe1' }],
    items = array2.reduce((s, { name }) => s.add(name).add(name.match(/^\D+/)[0]), new Set),
    result = array1.map(({ name, ...o }) => {
        if (!items.has(name)) {
            items.add(name);
            return { name, ...o };
        }
        var [letters, digits = 0] = name.split(/(\d+)/);
        digits = +digits;
        while (items.has(letters + ++digits));
        items.add(letters + digits);
        return { name: letters + digits, ...o };
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
...