0

I have an array of objects and I am trying to group them by similar property value. So lets say here is array

[  
  {  
    "size":"6.5",
    "width":"W"
  },
  {  
    "size":"6.5",
    "width":"M"
  },
  {  
    "size":"7.5",
    "width":"w"
  },
  {  
    "size":"8",
    "width":"M"
  },
  {  
    "size":"8",
    "width":"w"
  }
]

and i am trying to get something like this

[  
  {  
    "size_new":"6.5",
    "width_group":[  
      "W",
      "M"
    ]
  },
  {  
    "size_new":"7.5",
    "width_group":[  
      "M"
    ]
  },
  {  
    "size_new":"8",
    "width_group":[  
      "w",
      "M"
    ]
  }
]

My js looks like this

var _x = [];

for(var i = 0; i < x.length; i++){
    if(x[i].size == x[i+1].size){
        _x[i] = {
            new_size: x[i].size,
            width_group: [x[i].width,x[i+1].width]
        }
    }
}

Here is my fiddle http://jsfiddle.net/sghoush1/ogrqg412/1/

I am pretty sure that there is probably a giant gaping hole in my logic

5
  • possible duplicate of Remap array to object Commented Jan 28, 2015 at 0:30
  • 1
    var o={};x.forEach(function(a){o[a.size]=o[a.size]||{size: a.size, widths: []}; o[a.size].widths.push(a.width); });o; Commented Jan 28, 2015 at 0:34
  • @dandavis That doesn't produce the same output as requested. jsfiddle.net/uua3cyf1 Commented Jan 28, 2015 at 0:56
  • Use lodash groupBy function Commented Jan 28, 2015 at 1:28
  • 1
    One problem with your code is x[i].size == x[i+1].size, when i is the index of the last item then item i + 1 doesn't exist and hence your code gives Uncaught TypeError: Cannot read property 'size' of undefined Commented Jan 28, 2015 at 1:40

2 Answers 2

3

One simple way to do this would be to break this into several steps:

var sizeSorter = function(a, b) {return a - b};
var sizes = data.reduce(function(acc, item) {
    (acc[item.size] || (acc[item.size] = [])).push(item.width);
    return acc;
}, {}); //=> {8: ['M', 'W'], '6.5': ['W', 'M'], '7.5': ['W']}
Object.keys(sizes).sort(sizeSorter).map(function(size) {
    return {size_new: size, width_group: sizes[size]};
});

That sorting is necessary because the keys will be sorted in Array order, with small numbers like '8' before strings like '6.5'.

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

Comments

1

You need to search if you have already added a specific size and then update only its width. Otherwise insert a new object

var _x = x.reduce(function(p,v){
    var existing = p.filter(function(item){return item.new_size === v.size})[0];
    if (existing){
        existing.width_group.push( v.width );
    } else {
        p.push( {
            new_size: v.size,
            width_group:[v.width]
        } );
    }
    return p;
},[]);

Demo at http://jsfiddle.net/ogrqg412/3/

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.