2

I am working with highChart to create a column chart. Any how I reached to creating following arrayofObj via communicating 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
      });
    });
5
  • @T.J.Crowder Thanks, Of course I have tried first, But you are right, I have added my progress in question. 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. Commented Jul 20, 2016 at 16:12
  • Also, search is your friend. :-) stackoverflow.com/questions/36069213/…, stackoverflow.com/questions/14592799/…, stackoverflow.com/questions/38079037/… Commented Jul 20, 2016 at 16:13
  • Possible duplicate of Lodash create collection from duplicate object keys 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. Commented Jul 20, 2016 at 17:33

3 Answers 3

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.net/lodash/4.13.1/lodash.min.js"></script>

Sign up to request clarification or add additional context in comments.

Comments

2

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"])

Comments

1

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
}, {})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.