【问题标题】:Group and filter items from an array对数组中的项目进行分组和过滤
【发布时间】:2020-09-22 11:10:44
【问题描述】:

我有一个名为items 的数组,这里是数组内的数据样本:

[
   {
      "id":"123",
      "key":"xxx111@gmail.com",
      "status":"attempted"
   },
   {
      "id":"123",
      "key":"xxx111@gmail.com",
      "status":"waiting"
   },
   {
      "id":"123",
      "key":"xxx111@gmail.com",
      "status":"completed"
   },
   {
      "id":"123",
      "key":"xxx222@gmail.com",
      "status":"completed"
   },
   {
      "id":"456",
      "key":"xxx333@gmail.com",
      "status":"waiting"
   },
   {
      "id":"456",
      "key":"xxx444@gmail.com",
      "status":"attempted"
   },
   {
      "id":"456",
      "key":"xxx444@gmail.com",
      "status":"failed"
   },
   {
      "id":"456",
      "key":"xxx555@gmail.com",
      "status":"attempted"
   },
   {
      "id":"456",
      "key":"xxx555@gmail.com",
      "status":"waiting"
   }
]

我想对数组中的项目进行分组和过滤。我发现我可以创建第二个数组并将所有符合我的条件的项目推送到第二个数组中,但不确定如何实现这一点。

以下是分组和过滤的标准:

  1. idkey 分组,以便将具有相同idkey 的所有记录分组在一起,并可以在下一步中进行过滤。所以在这里我可以动态创建数组,它们看起来像这样:

数组 1:

[
   {
      "id":"123",
      "key":"xxx111@gmail.com",
      "status":"attempted"
   },
   {
      "id":"123",
      "key":"xxx111@gmail.com",
      "status":"waiting"
   },
   {
      "id":"123",
      "key":"xxx111@gmail.com",
      "status":"completed"
   }
]

数组 2:

[
   {
      "id":"123",
      "key":"xxx222@gmail.com",
      "status":"completed"
   }
]

数组 3:

[
   {
      "id":"456",
      "key":"xxx333@gmail.com",
      "status":"waiting"
   }
]

数组 4:

[
   {
      "id":"456",
      "key":"xxx444@gmail.com",
      "status":"attempted"
   },
   {
      "id":"456",
      "key":"xxx444@gmail.com",
      "status":"failed"
   }
]

数组 5:

[
   {
      "id":"456",
      "key":"xxx555@gmail.com",
      "status":"attempted"
   },
   {
      "id":"456",
      "key":"xxx555@gmail.com",
      "status":"waiting"
   }
]
  1. 上面的数组应该被status过滤:如果在数组中我有failedcompleted的状态,我不想再考虑这个数组了。符合条件的数组中的数据可以推送到我的最终数组中,我只需要 idkey 归档,我不需要查看不同的状态:

最终数组:

[
   {
      "id":"456",
      "key":"xxx333@gmail.com"
   },
   {
      "id":"456",
      "key":"xxx555@gmail.com"
   }
]

到目前为止,我已经尝试过了,但我无法得到想要的结果:

  if(items.length >= 1) {
      for (i = 0; i < items.length; i++) {
        key = items[i]["key"];
        status = items[i]["status"];
        id = items[i]["id"];

        var arr=[];
        if(items[i]["key"]==key && items[i]["id"]==id) {
          arr.push(items[i]["key"])
          arr.push(items[i]["id"])
        }
}

任何帮助将不胜感激。

【问题讨论】:

标签: javascript ecmascript-3


【解决方案1】:

您可以对数组进行分组、过滤和映射,其中包含没有status 的对象的数组。

const
    data = [{ id: "123", key: "xxx111@gmail.com", status: "attempted" }, { id: "123", key: "xxx111@gmail.com", status: "waiting" }, { id: "123", key: "xxx111@gmail.com", status: "completed" }, { id: "123", key: "xxx222@gmail.com", status: "completed" }, { id: "456", key: "xxx333@gmail.com", status: "waiting" }, { id: "456", key: "xxx444@gmail.com", status: "attempted" }, { id: "456", key: "xxx444@gmail.com", status: "failed" }, { id: "456", key: "xxx555@gmail.com", status: "attempted" }, { id: "456", key: "xxx555@gmail.com", status: "waiting" }],
    keys = ['id', 'key'],
    unwanted = ['failed', 'completed'],
    result = Object
        .values(data.reduce((r, o) => {
            const key = keys.map(k => o[k]).join('|');
            if (!r[key]) r[key] = [];
            r[key].push(o);
            return r;
        }, []))
        .filter(a => a.every(({ status }) => !unwanted.includes(status)))
        .map(a => a.map(({ status, ...rest }) => rest));

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

在非常古老的 JS 中

var data = [{ id: "123", key: "xxx111@gmail.com", status: "attempted" }, { id: "123", key: "xxx111@gmail.com", status: "waiting" }, { id: "123", key: "xxx111@gmail.com", status: "completed" }, { id: "123", key: "xxx222@gmail.com", status: "completed" }, { id: "456", key: "xxx333@gmail.com", status: "waiting" }, { id: "456", key: "xxx444@gmail.com", status: "attempted" }, { id: "456", key: "xxx444@gmail.com", status: "failed" }, { id: "456", key: "xxx555@gmail.com", status: "attempted" }, { id: "456", key: "xxx555@gmail.com", status: "waiting" }],
    keys = ['id', 'key'],
    unwanted = ['failed', 'completed'],
    temp = {},
    result = [],
    i, j, k, key;

outer: for (i = 0; i < data.length; i++) {
    key = '';

    for (j = 0; j < keys.length; j++) key += data[i][keys[j]] + '|';

    if (temp[key] === null) continue;

    if (temp[key] === undefined) temp[key] = [];

    for (j = 0; j < unwanted.length; j++) {
        if (data[i].status !== unwanted[j]) continue;
        temp[key] = null;
        continue outer;
    }

    temp[key].push({ id: data[i].id, key: data[i].key });
}

for (k in temp) {
    if (temp[k]) result.push(temp[k]);
}

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

【讨论】:

  • 谢谢,只是仔细检查一下,这在 ecma3 中可以工作吗?
  • 什么是 ecma 3?
  • 你需要这么老的js版本干什么?
猜你喜欢
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-28
  • 2023-02-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多