最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Transform a list of dictionaries into a dictionary of lists with Javascript - Stack Overflow

programmeradmin2浏览0评论

Is there a built-in Javascript function to transform a list of dictionaries:

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

into a dictionary of lists like this:

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

? If not what's the simplest way to do it in JS?

(It is a little-bit similar to matrix "transpose" operation).

Note: here it's a transpose and not a groupby like in Most efficient method to groupby on an array of objects

Is there a built-in Javascript function to transform a list of dictionaries:

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

into a dictionary of lists like this:

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

? If not what's the simplest way to do it in JS?

(It is a little-bit similar to matrix "transpose" operation).

Note: here it's a transpose and not a groupby like in Most efficient method to groupby on an array of objects

Share Improve this question edited Dec 21, 2020 at 12:04 Basj asked Dec 21, 2020 at 11:43 BasjBasj 46.4k110 gold badges452 silver badges804 bronze badges 6
  • Does this answer your question? Group by multiple values Underscore.JS but keep the keys and values – arizafar Commented Dec 21, 2020 at 11:50
  • using simple js Most efficient method to groupby on an array of objects – arizafar Commented Dec 21, 2020 at 11:52
  • 1 This question should be reopened. This is not even related to grouping of array elements. The second linked question is related but this is still different enough to justify a new question. – lex82 Commented Dec 21, 2020 at 12:07
  • I changed my answer to work with an unknown list of keys – Mister Jojo Commented Dec 21, 2020 at 12:36
  • I changed my answer to make it a universal function, in the idea of your matrix function – Mister Jojo Commented Dec 21, 2020 at 12:45
 |  Show 1 more ment

6 Answers 6

Reset to default 2

Assuming all objects have the same keys and your array is not empty, this will work:

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

There are certainly more efficient solutions but this is short and concise and not too bad in terms of efficiency.

Here's a fairly short and efficient method for general values.

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);

I don't think such a function exists, at least in vanilla JavaScript.

A simple, pure vanilla and clear to understand way of doing it would be like this:

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]);
    }
} 

This is definitely not the most concise or most optimized way of doing it, though it will work.

You can just restructure your array of dictionaries as such, and re-map it with Array.prototype.map

E.g. (The following practice requires to iterate the elements with map N * X times where N is the length of L and X is the amount of properties you'd want to have in D, ignore this if you have many properties you'd want to watch.)

But, this is the easiest readable approach that I'd want to introduce to you before the 2nd approach.

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);

Another approach I'd suggest is to use Array.prototype.reduce, this is by far favored in your case as it's easily expandable by adding more properties to the initial array.

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);

const D={day:[], count:[]};

    for(const item of L){
    D.day.push(item.day);
    D.count.push(item.count);
    }
 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]);
    }
 });
发布评论

评论列表(0)

  1. 暂无评论