0

I have this array of object. I am trying to rearrange them by given order or sequence.

E.g if I say oil should come on order = 1 then the object of oil should come on top and if I say petrol should be order = 3 then the object of petrol should come on 3rd place.

Here is something I have tried so far but I am not achieving the correct result:

Also here is a working jsfiddle:

https://jsfiddle.net/voqgs7j8/

var utilities = {
    "petrol": {
        "title": "Petrol",
        "price": 10
    },
    "oil": {
        "title": "Oil",
        "price": 12
    },
    "sugar": {
        "title": "Sugar",
        "price": 14
    },
    "flour": {
        "title": "Flour",
        "price": 65
    } ,
    "apple": {
        "title": "apple",
        "price": 20
    } ,
    "banana": {
        "title": "banana",
        "price": 30
    } ,
    "orange": {
        "title": "orange",
        "price": 19
    }               
};

//var getUtilityUserPreferences = {utilityOrders: []};// to test empty DB values
var getUtilityUserPreferences = {utilityOrders: [{"utility": "petrol", "order": 5}, {"utility": "oil", "order": 1}, {"utility": "flour", "order": 2}]};

var response = utilities;// by default it holds all same ordered values
if(getUtilityUserPreferences && getUtilityUserPreferences.utilityOrders && getUtilityUserPreferences.utilityOrders.length){

    // OH we found user defined orders, so calculation starts with empty response
    var response = {};
    var resPointer = 1;// holds current index of final response, where the obj will be pushed
    var dbArrIndex = 0;// current db arr index that is waiting for its turn, to be pushed

    // loop through all values and keep pushing in final response unless some DB values comes and get pushed first
    for(var key in utilities){

        if(dbArrIndex < getUtilityUserPreferences.utilityOrders.length){// if db arr is not finished yet, otherwise we are done with db array

            // trying to check if its time for DB values to be pushed, otherwise all of above loop will be pushed
            var matching = true;
            while(matching && dbArrIndex < getUtilityUserPreferences.utilityOrders.length){// loop can also finish db arr, so validating again

                if(getUtilityUserPreferences.utilityOrders[dbArrIndex].order == resPointer){
                    response[getUtilityUserPreferences.utilityOrders[dbArrIndex].utility] = utilities[getUtilityUserPreferences.utilityOrders[dbArrIndex].utility];resPointer++;
                    delete utilities[getUtilityUserPreferences.utilityOrders[dbArrIndex].utility];
                    matching = true;

                    dbArrIndex++;               
                }
                else{
                    matching = false;
                }

            }
        }
        if(utilities[key]){// could be null by upper if
            response[key] = utilities[key];resPointer++;
        }
    }
}
//DONE!!!!!

for(var key in response){

    //console.log(key);
}
console.log(response);
return response;
StormTrooper
  • 1,731
  • 4
  • 23
  • 37
  • 1
    why not take an array of sorted keys? – Nina Scholz Nov 20 '20 at 10:37
  • Objects never guarantee order. Use an array or `Map` instead. https://stackoverflow.com/a/5525820/2151050 – Adam Azad Nov 20 '20 at 10:37
  • Objects don't have any meaningful specific order, the iteration methods order the values/keys during an iteration. – Teemu Nov 20 '20 at 10:38
  • @NinaScholz Actually I am getting these object literals from 3rd party api where I don't have access. – StormTrooper Nov 20 '20 at 10:39
  • Make [an API](https://jsfiddle.net/ctqL6wyd/) for your data. Notice, that you can also break the each-loop by returning false if needed. The example is not a perfect generic object iterator, but can be developed further (though I suppose it's not possible to create a generic iterator fullfilling all the requirements). – Teemu Nov 20 '20 at 12:44

0 Answers0