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

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.