【问题标题】:Iterate and group the objects using map function使用 map 函数对对象进行迭代和分组
【发布时间】:2019-05-24 09:56:16
【问题描述】:

检查十进制 id 并相应地分组。

以下是示例和推荐的 JSON

JSON 示例

{
    "results": [
        {
            "name": "Download",
            "id": "1.1.1"
        },
        {
            "name": "Download",
            "id": "1.2"
        },
        {
            "name": "Download",
            "id": "1.3.2"
        },
        {
            "name": "Download",
            "id": "2"
        },
        {
            "name": "Download",
            "id": "2.3"
        },
        {
            "name": "Download",
            "id": "3.2"
        },
        {
            "name": "Download",
            "id": "3.5"
        },
        {
            "name": "Download",
            "id": "4.2"
        }
    ]
}

希望将上述 JSON 迭代并重新构建为以下推荐格式。

逻辑:应该检查id(带和不带小数)并根据数字对它们进行分组。

例如:

1, 1.1, 1.2.3, 1.4.5 => data1: [{id: 1},{id: 1.1}....] 
2, 2.3, 2.3.4 => data2: [{id: 2},{id: 2.3}....]
3, 3.1 => data3: [{id: 3},{id: 3.1}]

推荐的 JSON

{
    "results": [
        {
            "data1": [
                {
                    "name": "Download",
                    "id": "1.1.1"
                },
                {
                    "name": "Download",
                    "id": "1.2"
                },
                {
                    "name": "Download",
                    "id": "1.3.2"
                }
            ]
        },
        {
            "data2": [
                {
                    "name": "Download",
                    "id": "2"
                },
                {
                    "name": "Download",
                    "id": "2.3"
                }
            ]
        },
        {
            "data3": [
                {
                    "name": "Download",
                    "id": "3.2"
                },
                {
                    "name": "Download",
                    "id": "3.5"
                }
            ]
        },
        {
            "data4": [
                {
                    "name": "Download",
                    "id": "4.2"
                }
            ]
        }
    ]
}

我尝试了以下解决方案,但它没有对对象进行分组

var formatedJSON = [];
results.map(function(d,i) {
    formatedJSON.push({
        [data+i]: d
    })
});

提前致谢。

【问题讨论】:

标签: javascript arrays json loops


【解决方案1】:

你可以像这样使用reduce。这个想法是为每个data1data2 等创建一个键值对,这样这个对象中的值就是你在最终数组中需要的值。然后使用Object.values 将它们作为数组获取。

const sampleJson = {"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]}

const grouped = sampleJson.results.reduce((a, v) => {
    const key = `data${parseInt(v.id)}`;
    (a[key] = a[key] || {[key]: []})[key].push(v);
    return a;
},{});

console.log({results: Object.values(grouped)})

一个班轮/代码高尔夫:

let s={"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]},k;

console.log({results:Object.values(s.results.reduce((a,v)=>(k=`data${parseInt(v.id)}`,(a[k] = a[k]||{[k]:[]})[k].push(v),a),{}))})

【讨论】:

    【解决方案2】:

    给你:

    var data = {
        "results": [
            {
                "name": "Download",
                "id": "1.1.1"
            },
            {
                "name": "Download",
                "id": "1.2"
            },
            {
                "name": "Download",
                "id": "1.3.2"
            },
            {
                "name": "Download",
                "id": "2"
            },
            {
                "name": "Download",
                "id": "2.3"
            },
            {
                "name": "Download",
                "id": "3.2"
            },
            {
                "name": "Download",
                "id": "3.5"
            },
            {
                "name": "Download",
                "id": "4.2"
            }
        ]
    };
    
    
    let newSet = new Set();
    
    data.results.forEach(e => {
      let key = e.id.substring(0, e.id.indexOf('.'));
      console.log(key);
      if (newSet.has(key) == false) {
        newSet.add(key);
        newSet[key] = [];
        }
       newSet[key].push(e.id);
    });
    
    
    console.log(newSet);

    【讨论】:

      【解决方案3】:

      你会这样做:

      var data = {
          "results": [
              {
                  "name": "Download",
                  "id": "1.1.1"
              },
              {
                  "name": "Download",
                  "id": "1.2"
              },
              {
                  "name": "Download",
                  "id": "1.3.2"
              },
              {
                  "name": "Download",
                  "id": "2"
              },
              {
                  "name": "Download",
                  "id": "2.3"
              },
              {
                  "name": "Download",
                  "id": "3.2"
              },
              {
                  "name": "Download",
                  "id": "3.5"
              },
              {
                  "name": "Download",
                  "id": "4.2"
              }
          ]
      };
      
      var newData = {
        "results": {}
      };
      
      data.results.forEach(item => {
        var num = item.id.slice(0, 1);
        if (newData.results["data" + num]) {
          newData.results["data" + num].push(item);
        } else {
          newData.results["data" + num] = [item];
        }
      })
      
      data = newData;
      console.log(data);

      它的作用是遍历results 中的每个项目,获取该项目id 前面的数字,并检查名称data-{num} 的数组是否存在。如果数组存在,则将其推送。如果它不存在,则使用该项目创建它。

      【讨论】:

      • results 应该是一个数组,而不是一个对象 :)
      【解决方案4】:

      let input = getInput();
      
      let output = input.reduce((acc, curr)=>{
        let {id} = curr;
        let majorVersion = 'name' + id.split('.')[0];
        if(!acc[majorVersion]) acc[majorVersion]= [];
        acc[majorVersion].push(curr);
        return acc;
      },{})
        
      console.log(output)
        
        
        
      function getInput(){
        return [
        {
            "name": "Download",
            "id": "1.1.1"
        },
        {
            "name": "Download",
            "id": "1.2"
        },
        {
            "name": "Download",
            "id": "1.3.2"
        },
        {
            "name": "Download",
            "id": "2"
        },
        {
            "name": "Download",
            "id": "2.3"
        },
        {
            "name": "Download",
            "id": "3.2"
        },
        {
            "name": "Download",
            "id": "3.5"
        },
        {
            "name": "Download",
            "id": "4.2"
        }
      
        ]
        }

      【讨论】:

        【解决方案5】:

        使用 RegEx 的一种解决方案可进行更精细的控制,因为它可以轻松区分 1 和 11。 这也将确保即使最终出现相同的版本(比如最后是 1.9),它也会将其放回 data1。

        let newArr2 = ({ results }) =>
          results.reduce((acc, item) => {
            let key = "data" + /^(\d+)\.?.*/.exec(item.id)[1];
            let found = acc.find(i => key in i);
            found ? found[key].push(item) : acc.push({ [key]: [item] });
            return acc;
          }, []);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-10-18
          • 2020-10-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-19
          • 2022-08-05
          相关资源
          最近更新 更多