如何从对象数组中获取具有特定键唯一值的对象?

时间:2019-10-06 17:14:24

标签: javascript arrays

我有一个对象数组,如下所示。

 [{
        "_id": {
          "$oid": "5d9a16764f66ef0017a738ee"
        },
        "user": "tVH3U5Va4cBFiATvAACD",
        "team": "team1",
        "question": "5d98c7109d0e1d0017e3d31f",
        "date": {
          "$date": "2019-10-06T16:29:40.240Z"
        },
        "correct": "true",
        "ownId": "4",
        "blockId": "1"
    },
    {
        "_id": {
          "$oid": "5d9a167c4f66ef0017a738ef"
        },
        "user": "tVH3U5Va4cBFiATvAACD",
        "team": "team1",
        "question": "5d98c7109d0e1d0017e3d31f",
        "date": {
          "$date": "2019-10-06T16:29:46.694Z"
        },
        "correct": "true",
        "ownId": "4",
        "blockId": "1"
    },
    {
        "_id": {
          "$oid": "5d9a16824f66ef0017a738f0"
        },
        "user": "tVH3U5Va4cBFiATvAACD",
        "team": "team1",
        "question": "5d98c7109d0e1d0017e3d31e",
        "date": {
          "$date": "2019-10-06T16:29:52.900Z"
        },
        "correct": "true",
        "ownId": "5",
        "blockId": "1"
    }]

我需要获取最后一个date的对象,该对象具有唯一的userownIdblockId。唯一的意思是我只会得到一个user和相同的ownId相同的blockId。对于此示例,我只想获取,因为数组中的第一个对象和数组中的最后一个对象具有相同的userownIdblockId

[{
            "_id": {
              "$oid": "5d9a167c4f66ef0017a738ef"
            },
            "user": "tVH3U5Va4cBFiATvAACD",
            "team": "team1",
            "question": "5d98c7109d0e1d0017e3d31f",
            "date": {
              "$date": "2019-10-06T16:29:46.694Z"
            },
            "correct": "true",
            "ownId": "4",
            "blockId": "1"
        },
        {
            "_id": {
              "$oid": "5d9a16824f66ef0017a738f0"
            },
            "user": "tVH3U5Va4cBFiATvAACD",
            "team": "team1",
            "question": "5d98c7109d0e1d0017e3d31e",
            "date": {
              "$date": "2019-10-06T16:29:52.900Z"
            },
            "correct": "true",
            "ownId": "5",
            "blockId": "1"
        }]

我试图通过数组进行操作,但是通过这种方式,我只能在一个键中获得唯一的对象。我不知道怎么用几个键就能拥有它。

stat.forEach(function(item) {
  var i = unique.findIndex(x => x.user == item.user);
  if (i <= -1) {
    unique.push({
      id: item._id,
      user: item.user
    });
  }
});

2 个答案:

答案 0 :(得分:2)

您可以使用reduce()方法遍历数组,以建立具有user + ownId + blockId作为属性名称或哈希键的哈希表或对象。

迭代时,如果存在具有相同键的对象,则比较日期并将值替换为具有最新日期的对象。

var data = [{ "_id": { "$oid": "5d9a16764f66ef0017a738ee" }, "user": "tVH3U5Va4cBFiATvAACD", "team": "team1", "question": "5d98c7109d0e1d0017e3d31f", "date": { "$date": "2019-10-06T16:29:40.240Z" }, "correct": "true", "ownId": "4", "blockId": "1" }, { "_id": { "$oid": "5d9a167c4f66ef0017a738ef" }, "user": "tVH3U5Va4cBFiATvAACD", "team": "team1", "question": "5d98c7109d0e1d0017e3d31f", "date": { "$date": "2019-10-06T16:29:46.694Z" }, "correct": "true", "ownId": "4", "blockId": "1" }, { "_id": { "$oid": "5d9a16824f66ef0017a738f0" }, "user": "tVH3U5Va4cBFiATvAACD", "team": "team1", "question": "5d98c7109d0e1d0017e3d31e", "date": { "$date": "2019-10-06T16:29:52.900Z" }, "correct": "true", "ownId": "5", "blockId": "1" } ];

var result = Object.values(data.reduce((acc, curr) => {
  let value = acc[curr.user + curr.ownId + curr.blockId];

  if (!value || new Date(curr.date.$date) > new Date(value.date.$date)) {
    acc[curr.user + curr.ownId + curr.blockId] = curr;
  }

  return acc;
}, {}));

console.log(result);

答案 1 :(得分:1)

希望我了解您的目标是什么。这样的事情可能对您有用(我假设您的对象数组称为stat):

const seenOwnIds = [];
const seenBlockIds = [];
const seenUserIds = [];
const uniqueUserArray = [];

for (let obj of stat) {
    if ( seenOwnIds.includes(obj.ownId) || seenBlockIds.includes(obj.blockId) || seenUserIds.includes(obj.user) ) {
        continue;
    }
    else {
        seenOwnIds.push(obj.ownId);
        seenBlockIds.push(obj.blockId);
        seenUserIds.push(obj.user);
        uniqueUserArray.push(obj);
    }
};

let lastDate = null;
let lastDateObj = {};

for (let obj of uniqueUserArray) {
    const curDate = new Date(obj.date.$date);
    if ( lastDate == null || curDate > lastDate ) { 
        lastDate = curDate;
        lastDateObj = obj;
    }
}