简体   繁体   中英

Why is the following javascript array sort deciding that two of my sort order parameters are undefined?

This is copied directly from my code and my console log. As you can see it is an array of objects. I am trying to sort the objects according to the sort order I have defined in a separate object. It sorts 5 of the seven elements but seemingly arbitrarily it decides that two of the properties of the sort object are not defined. That object is stringified by my code and written to the log right before the line that says that it is undefined. Clearly it is not undefined. So what is happening here?

This object defines the sort order that I want to use.

const statSortOrder = {
"4043523819": 0, //impact
"1240592695": 1, //range
"155624089": 2,  //stablility
"943549884": 3,  //handling
"4188031367": 4, //reload speed
"4284893193": 5, //rounds per minute
"3871231066": 6 //magazine
};

This code should sort the array of objects according to this order. Note that I've got some extra stuff in here to spit detailed results of what is happening to the console. I'll copy the contents of the resulting log and the contents of the array "orderArray" further down.

console.log("STAT SORT ORDER: \n" + JSON.stringify(statSortOrder));
console.log("UNORDERED ARRAY: \n" + JSON.stringify(orderArray));
orderArray.sort((a,b) => {
    if(a.hash && statSortOrder[a.hash.toString()] && b.hash && statSortOrder[b.hash.toString()]) {
        console.log("statSorOrder[a.hash] = " + statSortOrder[a.hash.toString()] + " : statSortOrder[b.hash] = " + statSortOrder[b.hash.toString()]);
        return statSortOrder[a.hash.toString()] - statSortOrder[b.hash.toString()];
    } else {
        console.log("statSortOrder = " + JSON.stringify(statSortOrder) + "\n"
        + "No match because a.hash.toString() =  " + a.hash.toString() + " and statSortOrder[a.hash.toString()] = " + statSortOrder[a.hash.toString()] + "\n"
        + " and b.hash.toString() = " + b.hash.toString() + " and statSortOrder[b.hash.toString()] = " + statSortOrder[b.hash.toString()]);
        return -1;
    }
});
console.log("ORDER ARRAY: \n" + JSON.stringify(orderArray));

so here is what I capture in my log:

2017-10-14T16:31:40.594Z    2628c5d7-b0fd-11e7-8b39-9b4f450e9f47    statSorOrder[a.hash] = 2 : statSortOrder[b.hash] = 3
2017-10-14T16:31:40.594Z    2628c5d7-b0fd-11e7-8b39-9b4f450e9f47    statSorOrder[a.hash] = 3 : statSortOrder[b.hash] = 1
2017-10-14T16:31:40.594Z    2628c5d7-b0fd-11e7-8b39-9b4f450e9f47    statSorOrder[a.hash] = 2 : statSortOrder[b.hash] = 1
2017-10-14T16:31:40.594Z    2628c5d7-b0fd-11e7-8b39-9b4f450e9f47    statSorOrder[a.hash] = 3 : statSortOrder[b.hash] = 6
2017-10-14T16:31:40.594Z    2628c5d7-b0fd-11e7-8b39-9b4f450e9f47    
statSortOrder =
{
    "155624089": 2,
    "943549884": 3,
    "1240592695": 1,
    "3871231066": 6,
    "4043523819": 0,
    "4188031367": 4,
    "4284893193": 5
}

No match because a.hash.toString() = 3871231066 and 
statSortOrder[a.hash.toString()] = undefined
and b.hash.toString() = 4043523819 and statSortOrder[b.hash.toString()] = 0
2017-10-14T16:31:40.594Z    2628c5d7-b0fd-11e7-8b39-9b4f450e9f47    
statSortOrder =
{
    "155624089": 2,
    "943549884": 3,
    "1240592695": 1,
    "3871231066": 6,
    "4043523819": 0,
    "4188031367": 4,
    "4284893193": 5
}

No match because a.hash.toString() = 4043523819 and 
statSortOrder[a.hash.toString()] = undefined
and b.hash.toString() = 4188031367 and statSortOrder[b.hash.toString()] = 4
2017-10-14T16:31:40.594Z    2628c5d7-b0fd-11e7-8b39-9b4f450e9f47    statSorOrder[a.hash] = 4 : statSortOrder[b.hash] = 5

And here is the contents of the object array both before and after this sort operation:

Before:

 [ { "entityType": "DestinyStatDefinition", "index": 19, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Stability", "ciName": "stability", "hash": 155624089, "displayProperties": { "name": "Stability", "icon": "/img/misc/missing_icon_d2.png", "description": "How much or little recoil you will experience while firing the weapon.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "How much or little recoil you will experience while firing the weapon.", "id": 155624089 } , { "entityType": "DestinyStatDefinition", "index": 23, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Handling", "ciName": "handling", "hash": 943549884, "displayProperties": { "name": "Handling", "icon": "/img/misc/missing_icon_d2.png", "description": "The speed with which the weapon can be readied and aimed.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "The speed with which the weapon can be readied and aimed.", "id": 943549884 } , { "entityType": "DestinyStatDefinition", "index": 15, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Range", "ciName": "range", "hash": 1240592695, "displayProperties": { "name": "Range", "icon": "/img/misc/missing_icon_d2.png", "description": "Increases the effective range of this weapon.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "Increases the effective range of this weapon.", "id": 1240592695 } , { "entityType": "DestinyStatDefinition", "index": 21, "icon": "/img/theme/destiny/icons/icon_magazineSize.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Magazine", "ciName": "magazine", "hash": 3871231066, "displayProperties": { "name": "Magazine", "icon": "/img/theme/destiny/icons/icon_magazineSize.png", "description": "The number of shots which can be fired before reloading.", "hasIcon": true }, "hasIcon": true, "interpolate": false, "description": "The number of shots which can be fired before reloading.", "id": -423736230 } , { "entityType": "DestinyStatDefinition", "index": 14, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Impact", "ciName": "impact", "hash": 4043523819, "displayProperties": { "name": "Impact", "icon": "/img/misc/missing_icon_d2.png", "description": "Increases the damage inflicted by each round.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "Increases the damage inflicted by each round.", "id": -251443477 } , { "entityType": "DestinyStatDefinition", "index": 24, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Reload Speed", "ciName": "reload speed", "hash": 4188031367, "displayProperties": { "name": "Reload Speed", "icon": "/img/misc/missing_icon_d2.png", "description": "The time it takes to reload this weapon.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "The time it takes to reload this weapon.", "id": -106935929 } , { "entityType": "DestinyStatDefinition", "index": 13, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Rounds Per Minute", "ciName": "rounds per minute", "hash": 4284893193, "displayProperties": { "name": "Rounds Per Minute", "icon": "/img/misc/missing_icon_d2.png", "description": "The number of shots per minute this weapon can fire.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "The number of shots per minute this weapon can fire.", "id": -10074103 } ] 

After:

 [{ "entityType": "DestinyStatDefinition", "index": 15, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Range", "ciName": "range", "hash": 1240592695, "displayProperties": { "name": "Range", "icon": "/img/misc/missing_icon_d2.png", "description": "Increases the effective range of this weapon.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "Increases the effective range of this weapon.", "id": 1240592695 }, { "entityType": "DestinyStatDefinition", "index": 19, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Stability", "ciName": "stability", "hash": 155624089, "displayProperties": { "name": "Stability", "icon": "/img/misc/missing_icon_d2.png", "description": "How much or little recoil you will experience while firing the weapon.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "How much or little recoil you will experience while firing the weapon.", "id": 155624089 }, { "entityType": "DestinyStatDefinition", "index": 23, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Handling", "ciName": "handling", "hash": 943549884, "displayProperties": { "name": "Handling", "icon": "/img/misc/missing_icon_d2.png", "description": "The speed with which the weapon can be readied and aimed.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "The speed with which the weapon can be readied and aimed.", "id": 943549884 }, { "entityType": "DestinyStatDefinition", "index": 21, "icon": "/img/theme/destiny/icons/icon_magazineSize.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Magazine", "ciName": "magazine", "hash": 3871231066, "displayProperties": { "name": "Magazine", "icon": "/img/theme/destiny/icons/icon_magazineSize.png", "description": "The number of shots which can be fired before reloading.", "hasIcon": true }, "hasIcon": true, "interpolate": false, "description": "The number of shots which can be fired before reloading.", "id": -423736230 }, { "entityType": "DestinyStatDefinition", "index": 14, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Impact", "ciName": "impact", "hash": 4043523819, "displayProperties": { "name": "Impact", "icon": "/img/misc/missing_icon_d2.png", "description": "Increases the damage inflicted by each round.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "Increases the damage inflicted by each round.", "id": -251443477 }, { "entityType": "DestinyStatDefinition", "index": 24, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Reload Speed", "ciName": "reload speed", "hash": 4188031367, "displayProperties": { "name": "Reload Speed", "icon": "/img/misc/missing_icon_d2.png", "description": "The time it takes to reload this weapon.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "The time it takes to reload this weapon.", "id": -106935929 }, { "entityType": "DestinyStatDefinition", "index": 13, "icon": "/img/misc/missing_icon_d2.png", "hasComputedBlock": false, "aggregationType": 2, "redacted": false, "name": "Rounds Per Minute", "ciName": "rounds per minute", "hash": 4284893193, "displayProperties": { "name": "Rounds Per Minute", "icon": "/img/misc/missing_icon_d2.png", "description": "The number of shots per minute this weapon can fire.", "hasIcon": false }, "hasIcon": false, "interpolate": false, "description": "The number of shots per minute this weapon can fire.", "id": -10074103 } ] 

This

"4043523819": 0, //impact

returns a falsy value and it is causing a problem with the kind of checks you make. You could add one to all values in the sort order object statSortOrder .

Instead of:

if(a.hash && statSortOrder[a.hash.toString()] && b.hash && statSortOrder[b.hash.toString()]) {

... you should make a more precise check for key existence like this:

if(a.hash && a.hash.toString() in statSortOrder && b.hash && b.hash.toString() in statSortOrder) {

Secondly, the confusion is made greater because of a bug in the else part, where you output:

" and statSortOrder[a.hash.toString()] = " + statSortOrder[a.hash.toString]

... but you forgot to actually call toString and should have done:

" and statSortOrder[a.hash.toString()] = " + statSortOrder[a.hash.toString()]

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