【问题标题】:Transform a list of dictionaries into a dictionary of lists with Javascript使用 Javascript 将字典列表转换为列表字典
【发布时间】:2021-03-31 04:19:53
【问题描述】:

是否有内置的 Javascript 函数来转换字典列表

const L = 
      [ { "day": "20201210", "count": "100" } 
      , { "day": "20201211", "count": "120" } 
      , { "day": "20201212", "count":  "90" } 
      , { "day": "20201213", "count": "150" } 
      ] 

进入列表字典,如下所示:

const D = 
      { "day"   : [ "20201210", "20201211", "20201212", "20201213"] 
      , "count" : [ "100", "120", "90", "150"] 
      } 

?如果不是,在 JS 中最简单的方法是什么?

(有点类似于矩阵“转置”操作)。

注意:这里是转置,而不是 Most efficient method to groupby on an array of objects 中的 groupby

【问题讨论】:

标签: javascript list dictionary


【解决方案1】:
const D={day:[], count:[]};

    for(const item of L){
    D.day.push(item.day);
    D.count.push(item.count);
    }

【讨论】:

    【解决方案2】:

    我认为不存在这样的函数,至少在原生 JavaScript 中是这样。

    一个简单、纯粹的香草和清晰易懂的做法是这样的:

    var L = [
        {
            "day": "20201210",
            "count": "100"
        },
        {
            "day": "20201211",
            "count": "120"
        },
        {
            "day": "20201212",
            "count": "90"
        },
        {
            "day": "20201213",
            "count": "150"
        }
    ];
    var D = { };
    
    for (var dict in L)
    {
        for (var key in L[dict]) 
        {
            if (D[key] == null) {
                D[key] = [ ];
            }
            
            D[key].push(L[dict][key]);
        }
    } 
    

    这绝对不是最简洁或最优化的方式,尽管它会起作用。

    【讨论】:

      【解决方案3】:

      假设所有对象都具有相同的键并且您的数组不为空,这将起作用:

      let D = {};
      Object.keys(L[0]).forEach(k => {
          D[k] = L.map(o => o[k]);
      });
      

      当然有更有效的解决方案,但是这很简短,而且在效率方面也不算太差。

      【讨论】:

        【解决方案4】:
         const input = [{"day":"20201210","count":"100"},{"day":"20201211","count":"120"},{"day":"20201212","count":"90"},{"day":"20201213","count":"150"}];
         // Create a variable that will store the result
         let result = {};
         // Loop through the input with forEach
         input.forEach((element) => {
             // Loop through the keys 
            for(let key in element) {
                // Check if a key is not exist in the result 
                if(!result.hasOwnProperty(key)) {
                    // Then create an key and assign an empty array to it
                    result[key] = [];
                }
                // Push the elemnts to the array.
                result[key].push(element[key]);
            }
         });
        

        【讨论】:

          【解决方案5】:

          您可以像这样重组您的字典数组,然后用Array.prototype.map重新映射它

          例如(以下做法需要使用 map N * X 迭代元素,其中 NL 的长度,X 是您希望在 D 中拥有的属性数量,忽略这个,如果你有很多想看的属性。)

          但是,这是我想在第二种方法之前向您介绍的最容易阅读的方法。

          const L = [{"day":"20201210","count":"100"},{"day":"20201211","count":"120"},{"day":"20201212","count":"90"},{"day":"20201213","count":"150"}];
          
          const D = {
            'day': L.map(elem => elem['day']),
            'count': L.map(elem => elem['count']),
          };
          
          console.log(D);

          我建议的另一种方法是使用 Array.prototype.reduce,这在您的情况下是迄今为止最受青睐的,因为它可以通过向初始数组添加更多属性来轻松扩展。

          const L = [{"day":"20201210","count":"100"},{"day":"20201211","count":"120"},{"day":"20201212","count":"90"},{"day":"20201213","count":"150"}];
          
          const D = L.reduce((acc, cv) => {
            for (const propertyToGrab in acc) {
              if (cv.hasOwnProperty(propertyToGrab)) {
                acc[propertyToGrab].push(cv[propertyToGrab]);
              }
            }
          
             return acc;
          }, {
            'day': [],
            'count': []
          });
          
          console.log(D);

          【讨论】:

            【解决方案6】:

            这是一个相当短且有效的通用值方法。

            L.forEach(o => {
              Object.keys(o).forEach(k => {
                D[k] ||= [];
                D[k].push(o[k]);
              });
            });
            

            const L = [{
              "day": "20201210",
              "count": "100"
            }, {
              "day": "20201211",
              "count": "120"
            }, {
              "day": "20201212",
              "count": "90"
            }, {
              "day": "20201213",
              "count": "150"
            }]
            
            let D = {};
            
            L.forEach(o => {
              Object.keys(o).forEach(k => {
                D[k] ||= [];
                D[k].push(o[k]);
              });
            });
            
            console.log(D);

            【讨论】:

            • map() 生成您不需要的新数组。最好使用forEach(),因为您只对副作用感兴趣。
            猜你喜欢
            • 2017-04-23
            • 2021-10-13
            • 2018-08-21
            • 1970-01-01
            • 2015-07-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多