【问题标题】:How to group by json using reduce?如何使用reduce按json分组?
【发布时间】:2020-05-03 21:40:56
【问题描述】:

请看一下我当前的 json。我想按这个递归分组。

[{ "mode": "AR", "fname": "ta", "lname": "da", "w_lng": 
             "1.23", "w_lat": "2.23","other":"a"},
           { "mode": "AR", "fname": "ta", "lname": "Dash", "w_lng": 
             "1.23", "w_lat": "2.23","other":"b" },
           { "mode": "AR1", "fname": "ka", "lname": "ja", "w_lng": 
             "3.23", "w_lat": "4.23","other":"c" },
           { "mode": "AR", "fname": "Kiran", "lname": "Dash", "w_lng": 
             "5.23", "w_lat": "6.23","other":"d" },
           { "mode": "AR", "fname": "Milan", "lname": "Dash", "w_lng": 
             "7.23", "w_lat": "8.23","other":"e" },
           { "mode": "AR1", "fname": "ka", "lname": "ja", "w_lng": 
             "8.23", "w_lat": "9.23","other":"f" }]

我在寻找什么:

  {
  "mode": "AR",
  "results": [
    {
    "fname": "ta",
    "lname": "da",
    "w_level": [
                { "w_lng": "1.23",
                  "w_lat": "2.23"
                  "other":[{"other":"a","other":"b"}]
                },
                {"w_lng": "3.xx",
                 "w_lat": "4.xx"
                 "....":[........]
                }
              ]  
   }
   {
    "fname": "ka",
    "lame": "ja",
    "w_level": [
        {
            "w_lng": "6.xx",
            "w_lat": "5.xx"
            .....................
                }
              ]  
   }
 ]
},
{
  "mode": "AR1",
  "results": [
    {
    "fname": "ka",
    "lname": "ja",
    "w_level": [
                { "w_lng": "6.xx",
                  "w_lat": "5.xx"
                  "....":[........]
                }
              ]  
   }

 ]
}

我尝试过的:

Object.values(inArr.reduce((item, currItem) => {

var { mode, fname, lname } = currItem;

if (!item[mode]) item[mode] = { mode, results: [] }; 

let w_level = {};
for (let key of Object.keys(currItem)) {
  if (key !== "fname" && key !== 'lname' && key !== 'mode') {
    w_level[key] = currItem[key];
  }
}

item[mode].results.push({fname: fname, lname: lname, w_level: [w_level]});
return item;
}, {}))

但问题是 fname 和 lname 再次,即使它是相同的。我想递归分组。首先它将按模式分组。然后在此模式下按 fname+lname 分组。如果有任何相同,它将像树一样添加。

【问题讨论】:

  • 建议的结果是不可能的;您不能在对象中有重复的键。你能更新它以澄清你的意图吗?
  • 当我通过连接从表中获取数据时,就会出现这个 json。想想像按国家分组,然后按城市分组,然后按病房分组等等......
  • 对不起,我觉得我说得不够清楚。在您的结果中,您需要一个像这样的对象:{"fname": "ka", "fname": "ja"}。这样的对象是不可能的——试试吧。
  • @ggorlen 这可能只是一个错字,我相信 OP 的意思是 lname。不过还是不错的。
  • 毫无疑问,但是与输出中的... 省略号一起,使得它变得不那么清晰了。我认为 OP 会通过显示完全正确的输出来为自己提供服务,以避免任何混淆或歧义。

标签: javascript arrays node.js json reduce


【解决方案1】:

这是我的最终解决方案。用户可以指定分组的key。

const reduceArrayByKeys = (inArr, keys, restKey) => {
    const reduced = inArr.reduce((prev, cur) => {
        const copied = { ...cur }
        keys.forEach(key => delete copied[key])
        const existing = prev.find(item => keys.every(key => item[key] === cur[key]))
        if (existing) {
            existing[restKey].push(copied)
        } else {
            const newItem = {}
            keys.forEach(key => newItem[key] = cur[key])
            newItem[restKey] = [copied]
            prev.push(newItem)
        }
        return prev
    }, [])

    return reduced
}

我们可以指定要对数组进行分组的键。我们可以使用这个 reduceArrayByKeys 函数来根据需要对数组进行分组。下面是示例代码

const reduced = reduceArrayByKeys(inArr, ['mode'], 'results')
reduced.forEach(item => {
    const results = item.results
    item.results = reduceArrayByKeys(results, ['fname', 'lname'], 'w_level')

    item.results.forEach(child => {
        child.w_level = reduceArrayByKeys(child.w_level, ['w_lng', 'w_lat'], 'other')
    })
})

您也可以为 w_level 调用 reduceArrayByKeys 函数。

【讨论】:

  • 非常感谢。我现在正在检查。我希望它会起作用。
  • 假设我现在想减少 w_level。 reduce.forEach(item => { const w_level= item.results.w_level; item.results.w_level= reduceArrayByKeys(w_level, ['w_lng', 'w_lat'], 'other') }) 但它不起作用。你能检查一下吗?
  • item.results 是一个数组。您应该再次为 item.results 调用 forEach。所以 item.results.forEach(child => {child.w_level = reduceArrayByKeys(child.w_level, ...)})
  • 更改了我的数据。请看一下
  • 我更改了帖子。你的数据看起来不对。 {“模式”:“AR”,“fname”:“ta”,“da”:“Dash”,“w_lng”:“1.23”,“w_lat”:“2.23”,“其他”:“b”}。 "da": "Dash" 应该是 "lname": "da"?
猜你喜欢
  • 1970-01-01
  • 2012-08-07
  • 2023-01-12
  • 2015-09-02
  • 2022-11-24
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多