Удалите и получите максимальную строку для ключа в массиве объектов в JavaScript - PullRequest
0 голосов
/ 23 января 2019

У меня есть массив объектов.Этот массив имеет повторяющиеся строки.Необходимо идентифицировать дедуплицированные строки одним из ключей, имеющих максимальное значение.Пожалуйста, не e это уже отсортировано по id.

var myArray = [
  {id: 1, name: 'Foo Bar', email: 'foo@bar.com'},
  {id: 2, name: 'Foo Bar', email: 'foo@bar.com'},
  {id: 3, name: 'Foo Bar', email: 'foo@bar.com'},
  {id: 1, name: 'Jenny Block', email: 'jenny@bar.com'},
  {id: 2, name: 'Jenny Block', email: 'jenny@bar.com'},
];

Это образец массива объектов.Мне нужно получить следующее как вывод

var myArray = [  
  {id: 3, name: 'Foo Bar', email: 'foo@bar.com'},
  {id: 2, name: 'Jenny Block', email: 'jenny@bar.com'},
];



for (var i = 0; i < myArray.length; i++) {
    for (var j = i + 1; j < myArray.length; j++) {
        if (myArray[i].name === myArray[j].name && myArray[i].email === myArray[j].email) {
            myArray.splice(j,1);
        }
    }
}

код работает, только если есть 2 дубликата.Я хочу что-то, что работает для более чем 2 дубликатов и включает в себя только строку с максимальным идентификатором

Ответы [ 4 ]

0 голосов
/ 23 января 2019

Вот один дубль, который начинается с универсальной функции для задач такого рода: дедупликация списка значений путем принятия двух функций, одна генерирует ключ для совпадающих функций, а вторая выбирает, какая из пары совпадающих значений сохранить.

Мы можем предоставить что-то вроде ({name, email}) => `${name}~${email}` для генерации ключей, но я предпочитаю использовать JSON.stringify на всех, кроме id, поскольку это кажется более гибким. И выбор правильного соответствия просто (a, b) => a.id > b.id ? a : b

const dedupe = (genKey, choose) => xs => Object.values(xs.reduce((acc, x) => {
  const key = genKey(x)
  acc[key] = acc[key] ? choose(acc[key], x) : x
  return acc
}, {}))

const keepHighestId = dedupe(
  ({id, ...rest}) => JSON.stringify(rest), 
  (a, b) => a.id > b.id ? a : b
)

const myArray = [{"email": "foo@bar.com", "id": 1, "name": "Foo Bar"}, {"email": "foo@bar.com", "id": 2, "name": "Foo Bar"}, {"email": "foo@bar.com", "id": 3, "name": "Foo Bar"}, {"email": "jenny@bar.com", "id": 1, "name": "Jenny Block"}, {"email": "jenny@bar.com", "id": 2, "name": "Jenny Block"}]

console.log(keepHighestId(myArray))

Добавление таких абстракций, безусловно, не всегда лучший вариант, но может помочь разбить проблему на более управляемые части.

0 голосов
/ 23 января 2019

Это ведет себя так, потому что myArray.splice уменьшает длину исходного массива, и некоторые индексы могут быть пропущены.Чтобы избежать этого, вы можете выполнять итерацию с конца до начала массива и делать i-- сразу после операции splice, это должно помочь сохранить правильный порядок вашей итерации.Предоставленный массив уже отсортирован по id в порядке возрастания (я имею в виду те объекты с одинаковыми name и email), и таким образом вы получите уникальные объекты с самым высоким id:

var myArray = [
  {id: 1, name: 'Foo Bar', email: 'foo@bar.com'},
  {id: 2, name: 'Foo Bar', email: 'foo@bar.com'},
  {id: 3, name: 'Foo Bar', email: 'foo@bar.com'},
  {id: 1, name: 'Jenny Block', email: 'jenny@bar.com'},
  {id: 2, name: 'Jenny Block', email: 'jenny@bar.com'},
];

for (var i = myArray.length - 1; i >= 0; i--) {
    for (var j = i - 1; j >= 0; j--) {
        if (myArray[i].name === myArray[j].name && myArray[i].email === myArray[j].email) {
            myArray.splice(j,1);
            i--;
        }
    }
}

console.log(myArray);
0 голосов
/ 23 января 2019
var maxId = 0;
var duplicates = [];
var newArray = [];
for (var i = 0; i < myArray.length-1; i++) {
    maxId = myArray[i].id;
    if(!duplicates.includes(i)) {
        for (var j = i+1; j < myArray.length; j++) {  
            if (myArray[j].id > maxId) {
                maxId = myArray[j].id; 
                duplicates.push[j]; 
            }  
        }
    }
    myArray[i].id = maxId;
    newArray.push(myArray[i]);
}
0 голосов
/ 23 января 2019

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

var array = [{ id: 1, name: 'Foo Bar', email: 'foo@bar.com' }, { id: 2, name: 'Foo Bar', email: 'foo@bar.com' }, { id: 3, name: 'Foo Bar', email: 'foo@bar.com' }, { id: 1, name: 'Jenny Block', email: 'jenny@bar.com' }, { id: 2, name: 'Jenny Block', email: 'jenny@bar.com' }],
    result = array.reduce((r, o) => {
        var index = r.findIndex(p => o.name === p.name && o.email === p.email);
        if (index === -1) {
            r.push(o);
            return r;
        }
        if (r[index].id < o.id) {
            r[index] = o;
        }
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...