4

I have this data scenario:

var data = [
 {
  'name': 'social-button',
  'group': null
 }, {
  'name': 'social-button',
  'group': null
 }, {
  'name': 'social-button',
  'group': 'buttons'
 }, {
  'name': 'social-button',
  'group': null
 }, {
  'name': 'icon',
  'group': 'icons'
 }, {
  'name': 'other',
  'group': null
 }, {
  'name': 'icon',
  'group': null
 }
];

I would like to normalize this data to this:

var data = [
 {
  'name': 'social-button',
  'group': 'buttons'
 }, {
  'name': 'social-button',
  'group': 'buttons'
 }, {
  'name': 'social-button',
  'group': 'buttons'
 }, {
  'name': 'social-button',
  'group': 'buttons'
 }, {
  'name': 'icon',
  'group': 'icons'
 }, {
  'name': 'other',
  'group': null
 }, {
  'name': 'icon',
  'group': 'icons'
 }
];

So basically, I would like to ensure every element which have the same name should also have the same group, if just one of the same have one.

Does exists some node module could help in this?

Or maybe, does exist some smart way to do that?

0

3 Answers 3

3

You could use two loops, one to collect values in a hash table and one to assign.

var data = [{ 'name': 'social-button', 'group': null }, { 'name': 'social-button', 'group': null }, { 'name': 'social-button', 'group': 'buttons' }, {  'name': 'social-button', 'group': null }, { 'name': 'icon', 'group': 'icons' }, { 'name': 'other', 'group': null }, { 'name': 'icon', 'group': null }],
    hash = Object.create(null);

data.forEach(function (a) {
    hash[a.name] = hash[a.name] || a.group;
});

data.forEach(function (a) {
    a.group = a.group || hash[a.name];
});

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

3 Comments

You type faster than me :) Though I was going to use map to avoid changing the original.
it looks like a seach for an in-situ solution.
It worked flawlessly, also didn't changed the order of the items, and finally, it's very easy to read, thank you very much
0

You could first sort() your array so objects with group values come first and then use map() to create new array. You can use Object.assign() to clone objects so you can don't change your original data.

var data = [{"name":"social-button","group":null},{"name":"social-button","group":null},{"name":"social-button","group":"buttons"},{"name":"social-button","group":null},{"name":"icon","group":"icons"},{"name":"other","group":null},{"name":"icon","group":null}]

var result = data.sort((a, b) => b.group != null).map(function(o) {
  if (!this[o.name]) {
    this[o.name] = o.group
    return o
  } else {
    var obj = Object.assign({}, o);
    obj.group = this[o.name];
    return obj
  }
}, {})

console.log(result)

Comments

0

You can do that in one pass by using Array.prototype.reduce and a hash table - see demo below:

var data=[{'name':'social-button','group':null},{'name':'social-button','group':null},{'name':'social-button','group':'buttons'},{'name':'social-button','group':null},{'name':'icon','group':'icons'},{'name':'other','group':null},{'name':'icon','group':null}];

var result = data.reduce((function(hash){
  return function(p,c) {
    hash[c.name] = hash[c.name] || c;
    if(c.group)
      hash[c.name].group = c.group;
    p.push(hash[c.name]);
    return p;
  };
})(Object.create(null)), []);

console.log(JSON.stringify(result));
.as-console-wrapper{top:0;max-height:100%!important;}

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.