【问题标题】:How do i push same object value in to an array我如何将相同的对象值推入数组
【发布时间】:2021-09-10 16:12:16
【问题描述】:

我这几天一直在尝试处理下面的json。

[
  {createdAt: "2021-09-09 07:37", user_id: "admin", type: "click", query: "spider"},
  {createdAt: "2021-09-09 07:37", user_id: "admin", type: "search", query: "spider"},
  {createdAt: "2021-09-09 07:38", user_id: "user", type: "click", query: "hi"},
]

如果某个值是重复的,我想将它添加到一个新数组中。像这样

[
  {
    createdAt: "2021-09-09 07:37", 
    user_id: "admin",
    query: "spider",
    type: "click",
    result: [
     {createdAt: "2021-09-09 07:37", user_id: "admin", type: "search", query: "spider"}
    ]
  },
  {createdAt: "2021-09-09 07:38", user_id: "user", type: "click", query: "hi"}
]

lodash的groupBy函数最相似,但是我对JavaScript不熟悉。
任何人都可以帮助我如何处理那些 json?

【问题讨论】:

  • 您如何看待两个值重复?有什么标准吗?
  • 我认为日期和user_id,查询可以重复。

标签: javascript json typescript


【解决方案1】:

您可以使用MapforEach 轻松实现结果

const arr = [
  {
    createdAt: "2021-09-09 07:37",
    user_id: "admin",
    type: "click",
    query: "spider",
  },
  {
    createdAt: "2021-09-09 07:37",
    user_id: "admin",
    type: "search",
    query: "spider",
  },
  {
    createdAt: "2021-09-09 07:38",
    user_id: "user",
    type: "click",
    query: "hi",
  },
];

let map = new Map();

arr.forEach((obj) => {
  const { user_id, createdAt } = obj;
  if (map.has(`${user_id}|${createdAt}`))
    map.get(`${user_id}|${createdAt}`).push(obj);
  else map.set(`${user_id}|${createdAt}`, [obj]);
});

const result = [];
for (let [, v] of map) {
  const [first, ...rest] = v;
  const temp = Object.assign({}, first);
  if (rest.length) temp.result = rest;
  result.push(temp);
}

console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    下面是另一种方法。

    1. 使用一个Array.reduce构建一个字典来存储key出现的次数以及key的数据保存在哪里。

    2. 使用另一个Array.reduce 循环所有元素,然后应用您的逻辑。

    const data = [
      {createdAt: "2021-09-09 07:37", user_id: "admin", type: "click", query: "spider"},
      {createdAt: "2021-09-09 07:37", user_id: "admin", type: "search", query: "spider"},
      {createdAt: "2021-09-09 07:38", user_id: "user", type: "click", query: "hi"},
    ]
    
    function relayout() {
      const indexes = data.reduce((pre, cur) => {
        pre[`${cur.createdAt}-${cur.user_id}`] = [0, 0] // count, position in result array
        return pre
      }, {})
      return data.reduce((pre, cur) => {
        const key = `${cur.createdAt}-${cur.user_id}`
        if (indexes[key][0] > 0) {
          pre[indexes[key][1]].result = [
            ...(pre[indexes[key][1]].result || []),
            cur
          ]
        } else {
          pre.push(cur)
          indexes[key][1] = pre.length - 1
        }
        indexes[key][0] += 1
        return pre
      }, [])
    }
    
    console.log(relayout(data))

    【讨论】:

    • 我需要学习如何使用 reduce 。这对我来说是一个很好的答案。谢谢。
    猜你喜欢
    • 2020-01-24
    • 2020-10-03
    • 1970-01-01
    • 2019-12-25
    • 2023-04-01
    • 1970-01-01
    • 2016-12-25
    • 2019-03-24
    • 2017-05-01
    相关资源
    最近更新 更多