Удалить объекты "похожие элементы" в массиве на основе отметки времени

У меня есть массив (может быть и больше), в котором есть uid и timestamp.

Моя цель - циклически перебрать объект, и если их uid равны друг другу, оставить только объект с большей временной меткой.

[
  {
    "uid":"u55555",
    "timestamp":1536273731,
    "id":"8a655addf1293b6d780ff6469c0848dd",
    "name":"John Doe",
  },
  {
    "uid":"u55555",
    "timestamp":1536273831,
    "id":"8v8799817981mcmccm89c81282128cm2",
    "name":"John Doe",
  },
  {
    "uid":"u1111",
    "timestamp":1536253940,
    "id":"c8898202n2nu929n2828998228989h2h2",
    "name":"Test Testerson",
  },
  {
    "uid":"u55555",
    "timestamp":1536274940,
    "id":"fb990b1734e4aaea2e39315952e13123",
    "name":"John Doe",
  },
  {
    "uid":"u11111",
    "timestamp":1538275741,
    "id":"99s9hshs88s8g89898899898897a79s",
    "name":"Test Testerson",
  },
]

Кто-нибудь знает, как бы я это сделал?

Я играл со следующим, но не могу понять это правильно.

var result = signatures.filter(function (a) {

   //logic here

}, Object.create(null));

данные отсортированы?

Nina Scholz 13.09.2018 21:08

@NinaScholz, хотя в моем примере он может выглядеть отсортированным, я не могу рассчитывать на его сортировку

bryan 13.09.2018 21:11
0
2
52
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете создать объект, привязанный к guid, и пройти через свой массив, добавив элемент к объекту, если его либо еще нет, либо время меньше. Затем просто возьмите значения из этого объекта:

let arr = [{"uid":"u55555","timestamp":1536273731,"id":"8a655addf1293b6d780ff6469c0848dd","name":"John Doe",},{"uid":"u55555","timestamp":1536273831,"id":"8v8799817981mcmccm89c81282128cm2","name":"John Doe",},{"uid":"u1111","timestamp":1536253940,"id":"c8898202n2nu929n2828998228989h2h2","name":"Test Testerson",},{"uid":"u55555","timestamp":1536274940,"id":"fb990b1734e4aaea2e39315952e13123","name":"John Doe",},{"uid":"u11111","timestamp":1538275741,"id":"99s9hshs88s8g89898899898897a79s","name":"Test Testerson",},]

let newArr = Object.values(
  arr.reduce((obj, item) => {
    if (!obj[item.uid] || obj[item.uid].timestamp < item.timestamp)
      obj[item.uid] = item
    return obj
  }, {}))
console.log(newArr)

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

var array = [{ uid: "u55555", timestamp: 1536273731, id: "8a655addf1293b6d780ff6469c0848dd", name: "John Doe" }, { uid: "u55555", timestamp: 1536273831, id: "8v8799817981mcmccm89c81282128cm2", name: "John Doe" }, { uid: "u1111", timestamp: 1536253940, id: "c8898202n2nu929n2828998228989h2h2", name: "Test Testerson" }, { uid: "u55555", timestamp: 1536274940, id: "fb990b1734e4aaea2e39315952e13123", name: "John Doe" }, { uid: "u11111", timestamp: 1538275741, id: "99s9hshs88s8g89898899898897a79s", name: "Test Testerson" }],
    result = array.reduce((r, o) => {
        var index = r.findIndex(({ uid }) => uid === o.uid);
        if (index === -1) {
            return r.concat(o);
        }
        if (o.timestamp > r[index].timestamp) {
            r[index] = o;
        }
        return r;
    }, []);

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

Это создает новый объект, который использует ключи на основе UID; затем заполняет его только последними записями. Возможно, не самый маленький код, но это метод.

let sorted = {};
let original = [{
    "uid": "u55555",
    "timestamp": 1536273731,
    "id": "8a655addf1293b6d780ff6469c0848dd",
    "name": "John Doe",
  },
  {
    "uid": "u55555",
    "timestamp": 1536273831,
    "id": "8v8799817981mcmccm89c81282128cm2",
    "name": "John Doe",
  },
  {
    "uid": "u11111",
    "timestamp": 1536253940,
    "id": "c8898202n2nu929n2828998228989h2h2",
    "name": "Test Testerson",
  },
  {
    "uid": "u55555",
    "timestamp": 1536274940,
    "id": "fb990b1734e4aaea2e39315952e13123",
    "name": "John Doe",
  },
  {
    "uid": "u11111",
    "timestamp": 1538275741,
    "id": "99s9hshs88s8g89898899898897a79s",
    "name": "Test Testerson",
  },
];


original.forEach((item) => {
  if (sorted[item.uid] == undefined || sorted[item.uid].timestamp < item.timestamp) {
    // if key doesn't exist, create it
    // if key exists but timestamp is newer, replace it
    sorted[item.uid] = {
      uid: item.uid,
      timestamp: item.timestamp,
      id: item.id,
      name: item.name
    }
  }
});

console.log(sorted);
Ответ принят как подходящий

Вы можете отсортировать исходный массив по метке времени, а затем уменьшить его до набора уникальных uid, используя sort и reduce.

var data = [{"uid": "u55555","timestamp": 1536273731,"id": "8a655addf1293b6d780ff6469c0848dd","name": "John Doe",}, { "uid": "u55555", "timestamp": 1536273831, "id": "8v8799817981mcmccm89c81282128cm2", "name": "John Doe", }, { "uid": "u1111", "timestamp": 1536253940, "id": "c8898202n2nu929n2828998228989h2h2", "name": "Test Testerson", }, { "uid": "u55555", "timestamp": 1536274940, "id": "fb990b1734e4aaea2e39315952e13123", "name": "John Doe", }, { "uid": "u11111", "timestamp": 1538275741, "id": "99s9hshs88s8g89898899898897a79s", "name": "Test Testerson", }];

var result = data
  .sort((a,b) => b.timestamp - a.timestamp) //Sort by timestamp descending
  .reduce((a,i) => a.some(n=>n.uid === i.uid) ? a : [...a, i], []); //If item is already accounted for, ignore it

console.log(result);

Спасибо! Это кажется очень простым и лаконичным. Спасибо за комментарии, очень легко понять в чем дело.

bryan 13.09.2018 21:35

Рад, что смог помочь! Тем не менее, я обычно немного нервничаю из-за того, что могу делать что-то глупое всякий раз, когда мой ответ не совпадает с ответом Марка или Нины ... Я повторяю массив дважды (один раз для сортировки, один раз для уменьшения), тогда как я не Не верю, что это так с их. Я предполагаю, что мой может быть менее эффективным, хотя и с меньшим количеством строчек.

Tyler Roper 13.09.2018 21:37

Ах, очень верно. Что ж, я благодарен за пример @NinaScholz и Марка на случай, если это станет немного большей проблемой для эффективности.

bryan 13.09.2018 21:44

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

Mark 13.09.2018 21:49

Другие вопросы по теме