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

underscore.js - Javascript: Transform array of object response via lodash or underscore or corejavascript - Stack Overflow

programmeradmin0浏览0评论

I am working with highChart to create a column chart. Any how I reached to creating following arrayofObj via municating with database.

Now, I require to transform following source array of object to below output.

var source = [
{data: 258, name: '2014'}
{data: 18, name: '2016'}
{data: 516, name: '2014'}
{data: 0, name: '2014'}
{data: 354, name: '2014'}
{data: 18, name: '2016'}
]`

Convert this array of object to

Output

[{
    name: '2014',
    data: [258, 516, 354]
  }, {
    name: '2016',
    data: [18, 0, 18]
}]

Basically, I want my array to group by name (year) and data should be in array

Here is the solutions which i have applied.

var source = [];
_.each(source, function(singlerec) {
      source.push({
        name: singlerec.name,
        data: singlerec.data  // Here It only assign single record
      });
    });

I am working with highChart to create a column chart. Any how I reached to creating following arrayofObj via municating with database.

Now, I require to transform following source array of object to below output.

var source = [
{data: 258, name: '2014'}
{data: 18, name: '2016'}
{data: 516, name: '2014'}
{data: 0, name: '2014'}
{data: 354, name: '2014'}
{data: 18, name: '2016'}
]`

Convert this array of object to

Output

[{
    name: '2014',
    data: [258, 516, 354]
  }, {
    name: '2016',
    data: [18, 0, 18]
}]

Basically, I want my array to group by name (year) and data should be in array

Here is the solutions which i have applied.

var source = [];
_.each(source, function(singlerec) {
      source.push({
        name: singlerec.name,
        data: singlerec.data  // Here It only assign single record
      });
    });
Share Improve this question edited Jul 20, 2016 at 16:09 Denish asked Jul 20, 2016 at 16:03 DenishDenish 2,8102 gold badges25 silver badges33 bronze badges 5
  • @T.J.Crowder Thanks, Of course I have tried first, But you are right, I have added my progress in question. – Denish Commented Jul 20, 2016 at 16:11
  • Add what's wrong with the output of your solution. Also, with respect, your solution looks like it doesn't make any attempt at all to group things by name. Which is very much like asking someone else to add the grouping-by-name for you. – T.J. Crowder Commented Jul 20, 2016 at 16:12
  • Also, search is your friend. :-) stackoverflow./questions/36069213/…, stackoverflow./questions/14592799/…, stackoverflow./questions/38079037/… – T.J. Crowder Commented Jul 20, 2016 at 16:13
  • Possible duplicate of Lodash create collection from duplicate object keys – castletheperson Commented Jul 20, 2016 at 16:21
  • @T.J.Crowder Lodash is so succinct, that the solution is usually all or nothing. I don't feel that seeing the OP's attempt improves the question, just as long as they actually made a real attempt. Functional programming can be difficult to grasp, especially when people try to blend it with imperative programming. – castletheperson Commented Jul 20, 2016 at 17:33
Add a ment  | 

3 Answers 3

Reset to default 5

In Lodash, I always use _.groupBy and then _.map to the output format.

var source = [{"data":258,"name":"2014"},{"data":18,"name":"2016"},{"data":516,"name":"2014"},{"data":0,"name":"2014"},{"data":354,"name":"2014"},{"data":18,"name":"2016"}];

var output = _(source)
  .groupBy('name')
  .map(function(v, k) { return { name: k, data: _.map(v, 'data') } })
  .value();

console.log(output);
<script src="https://cdn.jsdelivr/lodash/4.13.1/lodash.min.js"></script>

I use a pure javascript function:

const pick = (obj, paths) => ({...paths.reduce((a, k) => ({...a, [k]: obj[k]}), {})})

function groupByAndConcat(data, groupBy, sums) {
    return data.reduce((results, r) => {
        const e = results.find((x) => groupBy.every((g) => x[g] === r[g]));
        if (e) {
            sums.forEach((k) => e[k] = [].concat(e[k], r[k]));
        } else {
            results.push(pick(r, groupBy.concat(sums)));
        }
        return results;
    }, []);
}

So given your sample source:

const source = [
    {data: 258, name: '2014'},
    {data: 18, name: '2016'},
    {data: 516, name: '2014'},
    {data: 0, name: '2014'},
    {data: 354, name: '2014'},
    {data: 18, name: '2016'},
];

console.log(groupByAndConcat(source, ["name"], ["data"]))

outputs:

[{ name: "2014", data: Array [258, 516, 0, 354] }, { name: "2016", data: Array [18, 18] }]

It is also possible to group by or do operations on several props:

groupByAndConcat(source, ["name","month"], ["data","data2"])

there's a way to iterate array once with reduce and even without lodash.

source.reduce((p, n) => {
    (p[n.name] || (p[n.name] = [])).push(n.data);
    return p
}, {})
发布评论

评论列表(0)

  1. 暂无评论