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

javascript - Underscore.js convert object to array - Stack Overflow

programmeradmin5浏览0评论

I'm relatively new to underscore.js and I have an object ing in from a REST service which looks like this (I have typed it out by hand and assigned it to a var here):

var production = [
    {key: ["wind", "1"], value: 5},
    {key: ["wind", "2"], value: 9},
    {key: ["wind", "3"], value: 11},
    {key: ["wind", "4"], value: 7},
    {key: ["solar", "1"], value: 1},
    {key: ["solar", "2"], value: 1},
    {key: ["solar", "3"], value: 2},
    {key: ["solar", "4"], value: 3},
    {key: ["oil", "1"], value: 15},
    {key: ["oil", "2"], value: 16},
    {key: ["oil", "3"], value: 22},
    {key: ["oil", "4"], value: 23},
];

Then further down, I have some code that parses this object and creates arrays for the items like so:

var orderedProduction = _.chain(production)
      .groupBy(function (entity) {
            return entity.key[0];
      })
      .map(function (values) { 
            return _.map(values, function (entity2) {
                  return entity2.value;
            });
      })
      .value();

This gives the following results:

orderedProduction  = [
  [5, 9, 11, 7],
  [1, 1, 2, 3],
  [15, 16, 22, 23]
]

Which loses the keys (wind/solar/oil). And is used to draw a graph. I'm further able to check if some of these arrays meet a certain threshold like so:

var threshold = _.map(orderedProduction  , function(arr) {
    return _.max(arr) > 10;
});

My requirements have now changed and I now need to filter out these arrays by its total sum, while retaining the key.

What I would like to end up with an object like so:

orderedProduction  = {
      "wind": [5, 9, 11, 7],
      "solar": [1, 1, 2, 3],
      "oil": [15, 16, 22, 23]
    }

It would be great if the fix included a way to sum up the values of the array and remove those that do not total up to a certain amount. (i.e. exclude solar, if it does not add up to 10).

Here is a jsfiddle I created to test this all out on: /


UPDATE: The solution I settled for was this:

var orderedProduction = _.chain(production)
    .groupBy(function (entity) {
        return entity.key[0];
    })
    .map(function (vals, key) {
        return [key, _.pluck(vals, 'value')]
    })
    .filter(function(arr) {
        var sum = 0;
        _.each(arr[1], function(num){
            sum += num;
        })
        return sum > 10;
    })
    .object()
    .value();

It also filters the values by a predetermined threshold (10 in this case).

I'm relatively new to underscore.js and I have an object ing in from a REST service which looks like this (I have typed it out by hand and assigned it to a var here):

var production = [
    {key: ["wind", "1"], value: 5},
    {key: ["wind", "2"], value: 9},
    {key: ["wind", "3"], value: 11},
    {key: ["wind", "4"], value: 7},
    {key: ["solar", "1"], value: 1},
    {key: ["solar", "2"], value: 1},
    {key: ["solar", "3"], value: 2},
    {key: ["solar", "4"], value: 3},
    {key: ["oil", "1"], value: 15},
    {key: ["oil", "2"], value: 16},
    {key: ["oil", "3"], value: 22},
    {key: ["oil", "4"], value: 23},
];

Then further down, I have some code that parses this object and creates arrays for the items like so:

var orderedProduction = _.chain(production)
      .groupBy(function (entity) {
            return entity.key[0];
      })
      .map(function (values) { 
            return _.map(values, function (entity2) {
                  return entity2.value;
            });
      })
      .value();

This gives the following results:

orderedProduction  = [
  [5, 9, 11, 7],
  [1, 1, 2, 3],
  [15, 16, 22, 23]
]

Which loses the keys (wind/solar/oil). And is used to draw a graph. I'm further able to check if some of these arrays meet a certain threshold like so:

var threshold = _.map(orderedProduction  , function(arr) {
    return _.max(arr) > 10;
});

My requirements have now changed and I now need to filter out these arrays by its total sum, while retaining the key.

What I would like to end up with an object like so:

orderedProduction  = {
      "wind": [5, 9, 11, 7],
      "solar": [1, 1, 2, 3],
      "oil": [15, 16, 22, 23]
    }

It would be great if the fix included a way to sum up the values of the array and remove those that do not total up to a certain amount. (i.e. exclude solar, if it does not add up to 10).

Here is a jsfiddle I created to test this all out on: http://jsfiddle/2mfjw3jk/


UPDATE: The solution I settled for was this:

var orderedProduction = _.chain(production)
    .groupBy(function (entity) {
        return entity.key[0];
    })
    .map(function (vals, key) {
        return [key, _.pluck(vals, 'value')]
    })
    .filter(function(arr) {
        var sum = 0;
        _.each(arr[1], function(num){
            sum += num;
        })
        return sum > 10;
    })
    .object()
    .value();

It also filters the values by a predetermined threshold (10 in this case).

Share Improve this question edited Sep 16, 2014 at 12:15 Husman asked Sep 16, 2014 at 11:00 HusmanHusman 6,90910 gold badges31 silver badges48 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7

You're almost there:

var orderedProduction = _.chain(production)
    .groupBy(function (entity) {
        return entity.key[0];
    })
    .map(function (vals, key) {
        return [key, _.pluck(vals, 'value')]
    })
    .object()
    .value();

returns

{ wind: [ 5, 9, 11, 7 ],
  solar: [ 1, 1, 2, 3 ],
  oil: [ 15, 16, 22, 23 ] }

You can simply use the map() function provided in javascript. The _.map() given is for backward patibility. Anyways, here is the code :

var obj = {};
production.map(function(data) {
    if(data.key[0] in obj) {
        obj[data.key[0]] += data.value;
    } else {
        obj[data.key[0]] = 0;
        obj[data.key[0]] += data.value;
    }
});
console.log(obj);

So what is does is that it loops throught the production array. There, it checks whether the key(for example, 'key' is the key) is in the obj object or not. If it is there then it simply increments its value or else makes a new key and assigns it 0 and then increments it.

Not the most optimized code but it works nicely.

This is probably not the best performing code, but it gets the job done using underscore.

Live Demo

var production = [
    {key: ["wind", "1"], value: 5},
    {key: ["wind", "2"], value: 9},
    {key: ["wind", "3"], value: 11},
    {key: ["wind", "4"], value: 7},
    {key: ["solar", "1"], value: 1},
    {key: ["solar", "2"], value: 1},
    {key: ["solar", "3"], value: 2},
    {key: ["solar", "4"], value: 3},
    {key: ["oil", "1"], value: 15},
    {key: ["oil", "2"], value: 16},
    {key: ["oil", "3"], value: 22},
    {key: ["oil", "4"], value: 23}
];

var orderedProduction =  _.chain(production)
    .groupBy(function (entity) {
        return entity.key[0];
    })
    .map(function(items, key){
        var returnVal = [key]; 
        var total = 0; 
        returnVal.push(_.map(items, function(obj){
            total += obj.value; 
            return obj.value; 
        })); 

        if(total > 10){
            return returnVal; 
        }

    })
    .filter(function(num) {
        return num !== undefined;
    })
    .object()
    .value();

console.log(production);
console.log(orderedProduction);
发布评论

评论列表(0)

  1. 暂无评论