-2

What I want to do is sort the elements of these arrays:

name[];
standing[];
value[];
maxvalue[];
id[];
repstring[];

By a sorting array:

var SortArr = [1,2,4,6,3,5,7,8,12,11,10,9...etc]

all the way up to 106 which is the length of these arrays.

This sorting array is meant to be a key to rearrange the data in a custom way, not alphabetically.

What is a way to do this efficiently? I've looked at trying to combine the above arrays into an object as I've been reading this might be the best way to do this(?) but I can't figure out how. I'm very new to javascript and coding in general so any pointers are welcome. Thanks

This is my code below:

}
//...
//this is all within a function called rep()


 //Declare things
  var name = [ ];
  var standing = [ ];
  var value = [ ];
  var maxvalue = [ ];
  var id = [ ];

  //For converting repstanding to strings
  var reputation = new Array ("Hated", "Hostile", "Unfriendly", "Neutral", "Friendly", "Honored", "Revered", "Exalted");

  //array holding converted strings for each faction
  var repstring = [ ];

  var count = toon.reputation.length; //this value is 106

  //Populate arrays
  for (i = 0; i < count; i++)
  {
    name[i] = toon.reputation[i].name; //string
    standing[i] = toon.reputation[i].standing; //number from 0-7
    value[i] = toon.reputation[i].value; // number from 0-21000
    maxvalue[i] = toon.reputation[i].max; //number from 3000-21000
    id[i] = toon.reputation[i].id //number from 1-1741
  }

  //Convert standing numbers to reputation string
  for (i=0; i < count; i++)
  {
    repstring[i] = reputation[standing[i]];
  }

  //Create output array
  var repInfo = new Array(
  name, standing, repstring, value, maxvalue, id, SortArr
  )

  //Output array
return repInfo;
}

EDIT: This is example output from my function: (note: this only shows values 1-5 for each array, there are 106 values in each array)

Name                Standing    Repstring   Value   MaxValue    ID      SortArr
The Black Prince        3       Neutral     2800    3000        1359        5
The Sons of Hodir       0       Hated       0       36000       1119        3
Booty Bay               3       Neutral     1875    3000        21          2
Zandalar Tribe          3       Neutral     0       3000        270         1
The Oracles             3       Neutral     0       3000        1105        4

Ok so what I want to do is rearrange these so that they are ordered by SortArr, so it would look like this:

Name                Standing    Repstring   Value   MaxValue    ID      SortArr
Zandalar Tribe          3       Neutral     0       3000        270         1
Booty Bay               3       Neutral     1875    3000        21          2
The Sons of Hodir       0       Hated       0       36000       1119        3
The Oracles             3       Neutral     0       3000        1105        4
The Black Prince        3       Neutral     2800    3000        1359        5
Ser3nity
  • 21
  • 4
  • please add some examples. – Nina Scholz Mar 24 '16 at 13:15
  • Hard to tell what you're asking. Show your input arrays and your output arrays, and a verbal description of the sorting algorithm. At the end of the day, you have to write a function that compares two objects and decides who comes first. – Ruan Mendes Mar 24 '16 at 13:15
  • You could just loop through your sorting array, get the value out of it, then pull the values from each of the arrays at the top into an object. Then store that in an array. Is that the kind of thing you're trying to do here? If so, it should be easy to write this up for you as a solution. – ManoDestra Mar 24 '16 at 13:16
  • You should really consider using an array of objects instead. – John Dvorak Mar 24 '16 at 13:25
  • How do I make this data into an array of objects? As mentioned I'm very new to javascript and can't figure it out. If this is a better way to do it I'm all for doing that. – Ser3nity Mar 24 '16 at 13:27
  • @ManoDestra I think this sounds like what I want yes. I've added some examples now also. How would I go about doing this? – Ser3nity Mar 24 '16 at 13:32

3 Answers3

0

If I understand the question correctly, you want to use the index of the number in your SortArray in your comparator function that you pass to sort.

// indices:             0  1  2  3  4  5  6
// When you see a 1, treat it like 0 (its index in array) in the comparator function
// When you see a 2, treat it like 2 (its index in array)         
var desiredSortOrder = [1, 3, 2, 7, 5, 4, 6];

var toSort = [1, 7, 2, 3, 4, 5, 6, 1, 2, 3, 7, 4, 5, 6];

// Map where the key is the number, and the value is the index in the desiredSortOrder array above
var mapToIndex = {};
desiredSortOrder.forEach((int, index) => mapToIndex[int] = index);

toSort.sort((a, b) => mapToIndex[a] - mapToIndex[b]);

console.log(toSort);
// [1, 1, 3, 3, 2, 2, 7, 7, 5, 5, 4, 4, 6, 6]
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • I'm not sure this is what I wanted to do. I've added some examples now maybe it makes more sense. desiredSortOrder sounds right, but I don't understand the rest of it – Ser3nity Mar 24 '16 at 13:36
  • @Ser3nity I'm pretty sure this is the core of what you are trying to do. I'm not going to write a full solution, but feel free to ask a further question. "I don't understand the rest of it" doesn't tell me much. – Ruan Mendes Mar 24 '16 at 13:50
0

Based on what you appear to be saying above, I would do the following...

var SortArr = [1, 2, 4, 6, 3, 5, 7, 8, 12, 11, 10, 9];

var collatedArray = [];
for (var i = 0; i < SortArr.length; i++) {
    index = SortArr[i];
    var collated = {
        name : name[index],
        standing : standing[index],
        value : value[index],
        maxvalue : maxvalue[index],
        id : id[index],
        repstring : repstring[index]
    }

    collatedArray.push(collated);
}

// Do what you want now with this collated array,
// which is an array of the objects you require.
// You can loop through them and access the properties
// via obj.id, obj.repstanding, etc.

E.g.

function getPlayer(id) {
    var player = null;
    for (var i = 0; i < collatedArray.length; i++) {
        if (collatedArray[i].id == id) {
            player = collatedArray[i];
            break;
        }
    }

    return player;
}

And just access the player object's properties thereafter...

player.id
player.repstanding
// etc...

If you need the objects returned to be immutable, it would be simple enough to alter this code to remove the public variables from the objects and allow access via getter methods instead.

You should really be thinking in terms of your model and storing an array of players (or whatever these things represent above), rather than storing arrays for each property of that specific model.

ManoDestra
  • 6,325
  • 6
  • 26
  • 50
  • Thanks for this. I think this is what I'm looking for. They are indeed players, or 1 specific player at a time and this is all the info about that player. Anyway, how do I output this data? In my old version I was storing all info in arrays, and I made a new array called RepInfo and returned this. Doesn't seem to be working when I try to return collatedArray – Ser3nity Mar 24 '16 at 13:55
  • All your info is stored in this new array now. You can loop through it and access via the loop index. Or you can just match against a player id, etc. I'll add some code above to illustrate. – ManoDestra Mar 24 '16 at 13:57
  • Thanks, this is perfect. I just can't seem to get it to output as a table on my spreadsheet like the arrays were doing, but I just need to do more reading – Ser3nity Mar 24 '16 at 14:35
  • Just loop through the objects and output them one at a time, comma delimited or whatever you require and refer to each property directly. Don't use arrays to store properties of model objects. – ManoDestra Mar 24 '16 at 14:38
  • Here's something that will help you with this: http://stackoverflow.com/questions/11257062/converting-json-object-to-csv-format-in-javascript – ManoDestra Mar 24 '16 at 14:41
0

You can use Array#forEach() and build a new array with the new indices.

var array = ['The Black Prince', 'The Sons of Hodir', 'Booty Bay', 'Zandalar Tribe', 'The Oracles'],
    sortOrder = [5, 3, 2, 1, 4];

function sort(array, sortOrder) {
    var result = [];
    sortOrder.forEach(function (a, i) {
        result[a - 1] = array[i];
    });
    return result;
}

document.write('<pre>' + JSON.stringify(sort(array, sortOrder), 0, 4) + '</pre>');

Just a hint, you can organise you data in rows, where all data to one item are collected in objects, like this representation:

[
    {
        "name": "The Black Prince",
        "standing": 3,
        "repstring": "Neutral",
        "value": 2800,
        "maxValue": 3000,
        "id": 1359,
        "sortOrder": 5
    },
    {
        "name": "The Sons of Hodir",
        "standing": 0,
        "repstring": "Hated",
        "value": 0,
        "maxValue": 36000,
        "id": 1119,
        "sortOrder": 3
    },
    // ...
]
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392