3

I have this object.

var orig_array =   [
    { "MSG_ID": { "lgth": "1", "payload": 0 } },
    { "STATE_1": { "lgth": "1", "payload": "XX" } },
    { "STATE_2": { "lgth": "1", "payload": "XXX" } },
    { "MSG_ID": { "lgth": "1", "payload": 1 } },
    { "STATE_1": { "lgth": "1", "payload": "X" } },
    { "STATE_2": { "lgth": "1", "payload": "XX" } },
    { "STATE_3": { "lgth": "6", "payload": "XXX" } },
    { "MSG_ID": { "lgth": "1", "payload": 2 } },
    { "STATE_1": { "lgth": "1", "payload": "XXXX" } }
];

I want to reduce the number of objects by grouping a few related objects into a single one.

The resulting array should look like this;

var processed_array =   [
    { "MSG_ID": { "lgth": "1", "payload": 0 }, "STATE_1": { "lgth": "1", "payload": "XX" },"STATE_2": { "lgth": "1", "payload": "XXX" } },
    { "MSG_ID": { "lgth": "1", "payload": 1 },"STATE_1": { "lgth": "1", "payload": "X" },"STATE_2": { "lgth": "1", "payload": "XX" },"STATE_3": { "lgth": "6", "payload": "XXX" } },
    { "MSG_ID": { "lgth": "1", "payload": 2 },"STATE_1": { "lgth": "1", "payload": "XXXX" } }
];

In orig_array, there are 3 objects with "MSG_ID". The subsequent "STATE_X" objects are combined into the above "MSG_ID" object. I have been staring at this problem for some time. Anyone can help or give some hints as a head-start?

4
  • 1
    i think you have to use lodash.com this lib Commented Jun 26, 2016 at 8:53
  • thanks. I will try lodash. Looks like a powerful library. Commented Jun 26, 2016 at 8:54
  • 1
    ya its powerful and there is also another one ,its name underscore. underscorejs.org Commented Jun 26, 2016 at 8:57
  • Your title and tags refer to JSON, but I do not see anything here related to JSON, which is a string-based format for interchanging information. Why are you using the word "JSON" to refer to regular old JavaScript objects? Just out of curiosity, from what book or other resource did you learn this incorrect use of JSON? Commented Jun 26, 2016 at 9:48

4 Answers 4

5

You could use Array#reduce and look for 'MSG_ID' as a group change.

var array = [{ "MSG_ID": { "lgth": "1", "payload": 0 } }, { "STATE_1": { "lgth": "1", "payload": "XX" } }, { "STATE_2": { "lgth": "1", "payload": "XXX" } }, { "MSG_ID": { "lgth": "1", "payload": 1 } }, { "STATE_1": { "lgth": "1", "payload": "X" } }, { "STATE_2": { "lgth": "1", "payload": "XX" } }, { "STATE_3": { "lgth": "6", "payload": "XXX" } }, { "MSG_ID": { "lgth": "1", "payload": 2 } }, { "STATE_1": { "lgth": "1", "payload": "XXXX" } }],
    grouped = array.reduce(function (r, a) {
        var key = Object.keys(a)[0];
        if (key === 'MSG_ID') {
            r.push({});
        }
        r[r.length - 1][key] = a[key];
        return r;
    }, []);

console.log(grouped);

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

2 Comments

Nina I believe in your ability but there is a problem in you implementation which is if any of objects contains more than one key.
right, i assume, that the object has only one property, as in the above stated array/object.
2

I think this would be the correct answer

var orig_json = [{
  "MSG_ID": { "lgth": "1", "payload": 0 }
}, {
  "STATE_1": { "lgth": "1", "payload": "XX" }
}, {
  "STATE_2": { "lgth": "1", "payload": "XXX" }
}, {
  "MSG_ID": { "lgth": "1", "payload": 1 }
}, {
  "STATE_1": { "lgth": "1", "payload": "X" }
}, {
  "STATE_2": { "lgth": "1", "payload": "XX" }
}, {
  "STATE_3": { "lgth": "6", "payload": "XXX" }
}, {
  "MSG_ID": { "lgth": "1", "payload": 2 }
}, {
  "STATE_1": { "lgth": "1", "payload": "XXXX" }
}];

var out = [],
  group = {};

orig_json
  .reduce((p, c) => p.concat(
    Object.keys(c).map(k => ({
      key: k,
      value: c[k]
    }))
  ), []).forEach(v => {
    if (v.key === "MSG_ID") {
      group = {};
      out.push(group);
    }
    group[v.key] = v.value
  });
console.log(out)

Comments

2

You can do with many js function eg.sort,map,forEach ...etc .I tried with my prefer function .sort

    i = -1;
    processed_array = [];
    orig_array.sort(function (r) {
        var k = Object.keys(r)[0];        
        if(k === "MSG_ID"){          
          i++;
          processed_array.push({});
        }
        processed_array[i][k] = r[k];
        return processed_array;
    }); 
console.log(processed_array);

2 Comments

Doesn't this only group on MSG_ID? OP wants any related to be combined - STATE_ 1, 2, and 3 in the example. Moreover, I doubt the example is an exhaustive list. I'm not entirely sure why sort() is your choice for solving this, since it just looks like you're using it as forEach. Only a very awkward one. On top of that, why are you even pushing an empty object to processed array only to change it immediately after? Why not just add the object you need to the processed array immediately, which saves some logic that is rather useless.
You can edit my answer as you want to change! Coz u r right. @Vld
1

I Think you need a groupBy method:

Array.prototype.groupBy = function(expresion) {
  var collection = [];
  this.forEach((v, i, a) => {
    var key = expresion(v, i, a);
    var group = collection.find(g => g.key === key);
    if (!group) {
      group = [];
      group.key = key;
      collection.push(group);
    }
    group.push(v);
  });

  return collection;
};

var orig_json = [{
  "MSG_ID": { "lgth": "1", "payload": 0 }
}, {
  "STATE_1": { "lgth": "1", "payload": "XX" }
}, {
  "STATE_2": { "lgth": "1", "payload": "XXX" }
}, {
  "MSG_ID": { "lgth": "1", "payload": 1 }
}, {
  "STATE_1": { "lgth": "1", "payload": "X" }
}, {
  "STATE_2": { "lgth": "1", "payload": "XX" }
}, {
  "STATE_3": { "lgth": "6", "payload": "XXX" }
}, {
  "MSG_ID": { "lgth": "1", "payload": 2 }
}, {
  "STATE_1": { "lgth": "1", "payload": "XXXX" }
}];

var newObj =orig_json
  .reduce((p, c) => p.concat(Object.keys(c).map(k => c[k])), [])
  .groupBy(v => Object.keys(v)[0]);
console.log(newObj);

1 Comment

How does this apply to the OP's question, if it does at all?

Your Answer

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