2
I have a json object which stores all the vehicle models with their brand. 

[{
"brand":"Audi","model":"A4"
},
{
"brand":"Audi","model":"A6"
},
{
"brand":"BMW","model":"Z4"
},
{
"brand":"Audi","model":"R8"
},
{
"brand":"Volvo","model":"v40"
},
{
"brand":"BMW","model":"5 Series"
}]

But the problem is , If I have 3 models for Audi, then the list is repeating the brand again and again thus filling my list with duplicate values. So I need to make a json object something like this: I just want to make a json object as follows using javascript or angularjs:

 [ {"brand":"Audi","models":["A4","A6","R8"]},
    {"brand":"BMW","models":["Z4","5 Series"]},
    {"brand":"Volvo","models":["v40"]}]
7
  • you could do groupBy on brand, refer this answer stackoverflow.com/a/24879563/2435473 Commented Oct 12, 2015 at 8:51
  • @PankajParkar I don't need to group it in UI side, I want to store it in another variable using code. Commented Oct 12, 2015 at 8:53
  • 1
    a correction on your terminology. You have an object - nothing to do with JSON Commented Oct 12, 2015 at 8:54
  • @JaromandaX sorry I am new to javascript and json Commented Oct 12, 2015 at 8:57
  • looking again, if that's a files contents, then, yes, it is JSON Commented Oct 12, 2015 at 9:00

5 Answers 5

1

you can make the JSON easily using both angular js or javascript. You can use following method in angular js . In javascript just use same type of loop like 'for'.

var model = {};
var brandList = [];
var returnObject = [];

var data = [
  {
    "brand": "Audi", "model": "A4"
  },
  {
    "brand": "Audi", "model": "A6"
  },
  {
    "brand": "BMW", "model": "Z4"
  },
  {
    "brand": "Audi", "model": "R8"
  },
  {
    "brand": "Volvo", "model": "v40"
  },
  {
    "brand": "BMW", "model": "5 Series"
  }
]

angular.forEach(data, function (dat, index) {
  if (brandList.indexOf(dat.brand) == -1) {
    brandList.push(dat.brand);
    model[dat.brand] = [];
    model[dat.brand].push(dat.model);
  } else {
    model[dat.brand].push(dat.model);
  }
});

angular.forEach(brandList, function (val, index) {
  var obj = {};
  obj.brand = val;
  obj.models = model[val];
  returnObject.push(obj);
});

Now returnObject will hold your desired JSON object.

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

6 Comments

Are you sure about that? - your code results in returnObject with only the last model for each brand
you need to swap model[dat.brand].push(dat.model); and model[dat.brand] = [dat.model];
You're also want to declare var brandList = [], model = {}, returnObject = []; - I think that's all the extra variables you use.
yeah, we all make mistakes
@ManijRai-ITH I got this result [{"brand":"Audi","models":["R8"]},{"brand":"BMW","models":["5 Series"]},{"brand":"Volvo","models":["v40"]}]
|
1

Given your input:

var input = [{
    "brand": "Audi",
    "model": "A4"
}, {
    "brand": "Audi",
    "model": "A6"
}, {
    "brand": "BMW",
    "model": "Z4"
}, {
    "brand": "Audi",
    "model": "R8"
}, {
    "brand": "Volvo",
    "model": "v40"
}, {
    "brand": "BMW",
    "model": "5 Series"
}];

you can achieve your desired result using Array.reduce -

var output = input.reduce(function(work, datum) {
    var n = work.brands.indexOf(datum.brand);
    if (n < 0) {
        n = work.brands.push(datum.brand) - 1;
        work.result.push({brand: datum.brand, models: []});
    }
    work.result[n].models.push(datum.model);
    return work;
}, {brands:[], result:[]}).result;

4 Comments

Wouldn't this result in an object instead of a array, as requested by the OP?!
indeed, well spotted :D
I am getting this result: {"Audi":{"brand":"Audi","models":["A4","A6","R8"]},"BMW":{"brand":"BMW","models":["Z4","5 Series"]},"Volvo":{"brand":"Volvo","models":["v40"]}}. Can you please help me to make it in the format which I mentioned
I know other answers are easier to read - but alternatives can sometimes teach :p
0
var input = [{
    "brand": "Audi",
    "model": "A4"
}, {
    "brand": "Audi",
    "model": "A6"
}, {
    "brand": "BMW",
    "model": "Z4"
}, {
    "brand": "Audi",
    "model": "R8"
}, {
    "brand": "Volvo",
    "model": "v40"
}, {
    "brand": "BMW",
    "model": "5 Series"
}];

// collect all brands models in a map
var brands_models = {};
for(var i=0; i < input.length; i++) {
 var dat = input[i];
 brands_models[dat.brand] = brands_models[dat.brand] || [];
 brands_models[dat.brand].push(dat.model);
}

// make array from map
var output = [];
foreach(var brand in brands_models) {
 output.push({
    "brand" : brand,
    "models": brands_models[brand]
  });
}

Comments

0

A proposal with only Array.prototype.forEach and Array.prototype.some.

var data = [{
        "brand": "Audi", "model": "A4"
    }, {
        "brand": "Audi", "model": "A6"
    }, {
        "brand": "BMW", "model": "Z4"
    }, {
        "brand": "Audi", "model": "R8"
    }, {
        "brand": "Volvo", "model": "v40"
    }, {
        "brand": "BMW", "model": "5 Series"
    }],
    combined = [];

data.forEach(function (a) {
    !combined.some(function (b) {
        if (a.brand === b.brand) {
            !~b.model.indexOf(a.model) && b.model.push(a.model);
            return true;
        }
    }) && combined.push({ brand: a.brand, model: [a.model] });
})
document.write('<pre>' + JSON.stringify(combined, 0, 4) + '</pre>');

Comments

0

I suggest another optimum way:

var arr = [
    {
        "brand": "Audi", "model": "A4"
    },
    {
        "brand": "Audi", "model": "A6"
    },
    {
        "brand": "BMW", "model": "Z4"
    },
    {
        "brand": "Audi", "model": "R8"
    },
    {
        "brand": "Volvo", "model": "v40"
    },
    {
        "brand": "BMW", "model": "5 Series"
    }
];
var copy = arr.slice(0);
var res = [];
while (copy.length) {//it  stop when copy is empty
    var a = {models: []};//create object
    var item = copy.shift();//item = copy[0], then copy[0] has deleted
    a.brand = item.brand;//current brand
    a.models.push(item.model);//first model has added

    copy.forEach(function (e, i) {
        if (e.brand === a.brand) {//find other items which they equal current brand
            a.models.push(e.model);//another models have added to models
            copy.splice(i, 1);//copy[i] has deleted
        }
    });
    res.push(a);//current brand item has added
}
console.log(res);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.