【问题标题】:Group key value from flat db by key parts only仅按关键部分对平面数据库中的键值进行分组
【发布时间】:2020-12-09 16:56:02
【问题描述】:

我从平面数据库收到一些数据,如下所示:

[{
        key: "user_15478",
        value: "xxx"
    }, {
        key: "user_name_15478",
        value: "xxx"
    }, {
        key: "user_age_15478",
        value: 5
    }, {
        key: "user_24547",
        value: "xxx"
    }, {
        key: "user_name_24547",
        value: "xxx"
    }, {
        key: "user_age_24547",
        value: 12
    }, {
        key: "user_42412",
        value: "xxx"
    }, {
        key: "user_name_42412",
        value: "xxx"
    }, {
        key: "user_age_42412",
        value: 42
    }
]

什么是更简单的方法,在 vanila js 中或使用像 lodash 这样的库来转换它,按密钥中的数字(15478、24547 等)分组。

例如:

[{
        15478: [{
                key: "user_15478",
                value: "xxx"
            }, {
                key: "user_name_15478",
                value: "xxx"
            }, {
                key: "user_age_15478",
                value: 5
            }
        ]
    }, {
        24547: [{
                key: "user_24547",
                value: "xxx"
            }, {
                key: "user_name_24547",
                value: "xxx"
            }, {
                key: "user_age_24547",
                value: 12
            }
        ]
    }, {
        42412: { {
                key: "user_42412",
                value: "xxx"
            }, {
                key: "user_name_42412",
                value: "xxx"
            }, {
                key: "user_age_42412",
                value: 42
            }
            ]
        }
        ]

提前感谢您的帮助。

【问题讨论】:

    标签: javascript arrays sorting object lodash


    【解决方案1】:

    这是使用Array.reduce()的解决方案

    const transformed = data.reduce((acc, user) => {
        const [ key ] = user.key.match(/\d+$/);
        if (!(key in acc)) {
            acc[+key] = [];
        }
        acc[+key].push(user);
        return acc;
    }, {});
    

    给定data 是:

    [{
        key: "user_15478",
        value: "xxx"
    }, {
        key: "user_name_15478",
        value: "xxx"
    }, {
        key: "user_age_15478",
        value: 5
    }, {
        key: "user_24547",
        value: "xxx"
    }, {
        key: "user_name_24547",
        value: "xxx"
    }, {
        key: "user_age_24547",
        value: 12
    }, {
        key: "user_42412",
        value: "xxx"
    }, {
        key: "user_name_42412",
        value: "xxx"
    }, {
        key: "user_age_42412",
        value: 42
    }];
    

    【讨论】:

      【解决方案2】:

      如果您的输入数组未排序,那么您首先需要根据key 对其进行排序。 所以排序后会是这样的:

      [{key: "user_15478",
       value: "xxx"
       },
      {key: "user_24547",
       value: "xxx"
       },
      .... //then _age wise
      {key: "user_age_42412",
       value: "xxx"
       },
      ... //then _name wise 
      {key: "user_name_42412",
       value: "xxx"
       },
      ]
      
      

      然后继续使用 reduce 将对象推送到累加器

      let arr= [ { key: "user_15478", value: "xxx" }, { key: "user_name_15478", value: "xxx" }, { key: "user_age_15478", value: 5 }, { key: "user_24547", value: "xxx" }, { key: "user_name_24547", value: "xxx" }, { key: "user_age_24547", value: 12 }, { key: "user_42412", value: "xxx" }, { key: "user_name_42412", value: "xxx" }, { key: "user_age_42412", value: 42 }, ];
      
      arr = arr.sort((a, b) => a.key > b.key ? 1 : -1)
      
      let result=arr.reduce((acc, val) => {
        let field = val.key.split("_")
        if (field.length === 2) {
          acc[field[1]] = [{ ...val
          }]
        }
        else
        acc[field[2]].push(val)
        return acc;
      }, {})
      let wrappedResult=Object.keys(result).map(key=>({[key]:result[key]}))
      console.log(wrappedResult)

      【讨论】:

        【解决方案3】:

        您可以使用reduce 和内部回调函数检查使用lastIndexOf 来获取最后一个_。然后检查累加器对象是否存在与数字相同的任何键。如果没有,则创建密钥并为其添加值。

        let data = [{
            key: "user_15478",
            value: "xxx"
          },
          {
            key: "user_name_15478",
            value: "xxx"
          },
          {
            key: "user_age_15478",
            value: 5
          },
          {
            key: "user_24547",
            value: "xxx"
          },
          {
            key: "user_name_24547",
            value: "xxx"
          },
          {
            key: "user_age_24547",
            value: 12
          },
          {
            key: "user_42412",
            value: "xxx"
          },
          {
            key: "user_name_42412",
            value: "xxx"
          },
          {
            key: "user_age_42412",
            value: 42
          }
        ];
        
        let newData = data.reduce((acc, curr) => {
          const _key = curr.key;
          const getNum = _key.substr(_key.lastIndexOf('_') + 1, _key.length);
          if (!acc[getNum]) {
            acc[getNum] = []
          }
          acc[getNum].push(curr)
          return acc;
        }, {});
        console.log([newData])

        【讨论】:

        • 非常感谢您的快速响应,我实际上认为我的数据结构与我提供的示例有点不同,因为当我在我的数据上尝试您的代码时,我得到 data.reduce 不是一个函数,在它工作的示例数据上。这里有两个数据结构(原文和例子):pasteboard.co/JnevTJp.jpg
        • 好的,我找到了解决方案,我的数据是一个对象,所以我只是用 Object.values(data) 包装它,例如: let newData = Object.values(data).reduce((acc, curr) => { 等等...完美运行,非常感谢!
        猜你喜欢
        • 2022-12-09
        • 1970-01-01
        • 2015-08-06
        • 2012-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-16
        • 1970-01-01
        相关资源
        最近更新 更多