简体   繁体   中英

how to write this javascript method in better way?

Can you improve on this? (declaring multiple arrays, too many if conditions and push) is there any way that i can group all this together?

prepareGroupMarkers: function(groups){
        var groupLevels = new Array();
        var level1 = [],
            level2 = [],
            level3 = [], 
            level4 = [],
            level5 = [];

        for(var i = 0; groups.length > i; i++){
            if(groups[i].level == 1) {
                level1.push(groups[i]);
            } else if(groups[i].level == 2) {
                level2.push(groups[i]);
            } else if(groups[i].level == 3) {
                level3.push(groups[i]);
            } else if(groups[i].level == 4) {
                level4.push(groups[i]);
            } else if(groups[i].level == 5) {
                level5.push(groups[i]);
            }
        }
        var pluginArrayArg = new Array();
            pluginArrayArg.push(level1);
            pluginArrayArg.push(level2);
            pluginArrayArg.push(level3);
            pluginArrayArg.push(level4);
            pluginArrayArg.push(level5);
        var jsonArray = JSON.parse(JSON.stringify(pluginArrayArg))
        return jsonArray;
    },

Thanks for all your responses!!

Here is my scenario, I have a huge collection of values in my JSON (its built based on tree structure like shown in the below image). And the above method is written to get the groups at each level. Actual json structure is so huge and it will have > 20K records.

在此处输入图片说明

groups":[
    {
        "latitude": 10.44333333333,
        "longitude": 77.55,
        "level": 1,
        ...
        ...
        ...
    },
    {
        "latitude": 16.347745,
        "longitude": 77.684620,
        "level": 4,
        ...
        ...
        ...
    },
    {
        "latitude": 16.34333333333,
        "longitude": 77.45,
        "level": 1,
        ...
        ...
        ...
    },
    {
        "latitude": 16.34333333333,
        "longitude": 77.45,
        "level": 2,
        ...
        ...
        ...
    },
    ...
    ...
    ...

And it will be really helpful, if the solution has better performance since the data we are handling is really huge.

A few small fixes: Save some cycles by using switch, and the push can be done in single line. Something like below:

prepareGroupMarkers: function(groups){
    var groupLevels = new Array();
    var level1 = [], level2 = [], level3 = [], level4 = [], level5 = [];

    for(var i = 0; groups.length > i; i++){
        switch(groups[i].level)
        {
            case 1:
                level1.push(groups[i]);
                break;
            case 2:
                level2.push(groups[i]);
                break;
            case 3:
                level3.push(groups[i]);
                break;
            case 4:
                level4.push(groups[i]);
                break;
            case 5:
                level5.push(groups[i]);
                break;
        }
    }
    var pluginArrayArg = new Array();
    pluginArrayArg.push(level1, level2, level3, level4, level5);
    var jsonArray = JSON.parse(JSON.stringify(pluginArrayArg))
    return jsonArray;
}

You can have a array of array and push the values to the array at based on the value of the level property

I assume you are doing the JSON.parse(JSON.stringify()) to make a deep copy of the object(may not always work), if not you can directly return pluginArrayArg

 var obj = { prepareGroupMarkers: function(groups) { var pluginArrayArg = [ [], [], [], [], [] ]; for (var i = 0; groups.length > i; i++) { pluginArrayArg[groups[i].level - 1].push(groups[i]); } return JSON.parse(JSON.stringify(pluginArrayArg)); } } var array = obj.prepareGroupMarkers([{ level: 1 }, { level: 5 }, { level: 2 }, { level: 2 }, { level: 4 }, { level: 4 }, { level: 1 }, { level: 5 }, { level: 1 }]); result.innerText = JSON.stringify(array, null, 2); 
 <pre id="result"></pre> 

I assume you aren't using ES6 or other modern JS, so I'll rewrite it old skool. I also assume 1 <= level >= 5 .

prepareGroupMarkers: function(groups) {
    var result= [[],[],[],[],[]];
    for (var i= 0; i < groups.length; ++i) {
        result[groups[i].level-1].push(groups[i]);
    }
    return result;
}

That should get you the same result. BTW, instead of new Array() just use [] . Also, why stringify then parse? No purpose.

EDIT: Since you asked, here is the ES6 equivalent (again assuming a fixed 5-level output):

function prepareGroupMarkers_ES6(groups) {
  return groups.reduce((result, item) => {
    result[item.level - 1].push(item);
    return result;
  }, [[],[],[],[],[]]);
}

Yes definitely, do it like this, use reduce

 function prepareGroupMarkers(groups) { var levels = groups.reduce(function (prev, cur) { var curLevel = cur.level - 1; prev[curLevel] = prev[curLevel] || []; prev[curLevel].push(cur); return prev; }, []); var pluginArrayArg = []; Array.prototype.push.apply(pluginArrayArg, levels); return pluginArrayArg; }; document.write(JSON.stringify(prepareGroupMarkers([{level: 1}, {level: 2}, {level: 1}, {level: 3}, {level: 4}, {level: 5}, {level: 3}]))); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM