0

I would like to rearrange an array of objects in javascript, which looks like this:

[{ year: "1950-12-20", product: ["product 1", "product 2, "product 3"] }, { year: "1951-12-20", product: ["product 3", "product 2"] }, { year: "1952-12-20", product: ["product 3", "product 4"] }]

so that I get two arrays, one with the products and one with the years when they appear.

a = ["product 1", "product 2", "product 3", "product 4"]
b = ["1950-12-20", [ "1950-12-20, "1951-12-20"],["1950-12-20", "1951-12-20", "1952-12-20"],"1952-12-20"]

I have tried to loop through each object through nestled for-loops, but how do I treat the array of strings in the object array in a nice way?

2
  • What does "treat the array of strings in the object array in a nice way?" mean? What is wrong with what you have now? Commented Nov 29, 2012 at 14:56
  • @Marcin: I have tried to map the data so that I have an array like this: data = [["1950-12-20", ["product 1", "product 2, "product 3"]],...], and then a for-loop: for ( var i = 0; i < data.length; i++ ) { for ( var j = 0; j < data[i][1].length; j++ ) {} }. Inside the for-loops I try to add the new products to an array using .push. Commented Nov 29, 2012 at 15:05

2 Answers 2

1

I don't know what kind of loop you have tested, but this type of code is not so long for what has to be done :

var data = [{ year: "1950-12-20", product: ["product 1", "product 2", "product 3"] }, { year: "1951-12-20", product: ["product 3", "product 2"] }, { year: "1952-12-20", product: ["product 3", "product 4"] }];

var nbData = data.length, iData;
var years = [], products = [], dictProductsYear = {};
var nbProducts, iProduct, p;


// Loop through years
for(iData = 0; iData < nbData; iData ++) {
    products = data[iData].product;
    nbProducts = products.length;

    // Add the current year to the concerned products
    for(iProduct = 0; iProduct < nbProducts; iProduct ++) {
        p = products[iProduct];

        // Registered product
        if(dictProductsYear[p]) dictProductsYear[p].push(data[iData].year);
        // Unregistered one
        else dictProductsYear[p] = [ data[iData].year ];
    }
}

var yearList = [], productList = [];

// Flatten the dictionary in 2 lists
for(p in dictProductsYear) {
    productList.push(p);
    yearList.push(dictProductsYear[p]);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I tried to generate an array using .map of the object array, but this much nicer to keep the array of objects intact. I will try it out.
1

This looks a bit like @Samuel Caillerie's code, but is more concise:

var data = [{ year: "1950-12-20", product: ["product 1", "product 2", "product 3"] }, { year: "1951-12-20", product: ["product 3", "product 2"] }, { year: "1952-12-20", product: ["product 3", "product 4"] }];

var yearsByProd = {};
for (var i=0; i<data.length; i++) {
    var prod = data[i].product;
    for (var j=0; j<prod.length; j++) {
         if (prod[j] in yearsByProd)
             yearsByProd[prod[j]].push(data[i].year);
         else
             yearsByProd[prod[j]] = [data[i].year];
    }
}
var a, b;
b = (a = Object.keys(yearsByProd).sort()).map(function(prod) {
    // add an if-else-statement here if you want to extract single years from their array
    return yearsByProd[prod];
});

3 Comments

Yes, but be careful that Object.keys and Array.prototype.map are not implemented cross-browser (see MDN Object.keys and MDN Array.prototype.map respectively, not for IE<9 for example).
@Bergi: Works very well, but I think I will need support for IE < 9.
@SamuelCaillerie: Yeah, should've mentioned that. Thanks for the links to the shims, most complainers don't mention them :-)

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.