Summarizing a javascript array of strings

2019-08-14 01:14发布

问题:

I have a variable length array of strings declared in javascript that contains Dungeons and Dragons class names. An example of this is below:

var class_names = new Array("Wizard", "Wizard", "Wizard", "Sorcerer", 
    "Sorcerer", "Ultimate Magus");

In my HTML, I use the javascript window.onload function to set a variety of variables from the javascript file to build the content of the page being displayed locally.

For things like name, this is easy:

document.getElementById('charname').innerHTML = name[0];

But for the class info, I don't want to just pump out a massive string of class names, I want it condensed down. Using the example 'class_names' above, I want to end up with a string that looks like this:

"Wizard 3, Sorcerer 2, Ultimate Magus 1"

i.e. the number after each class name should be the number of repetitions found in the array.

Anyone have an idea how to make this happen on the fly, so when I alter the javascript file to add more class data to class_names, it is displayed appropriately on my HTML page?

Thanks in advance for any help I get on this pet project (namely creating a HTML page for each character in my campaign that can be printed out as a character sheet....it's far better than manually writing a page for each character, or handwriting it on vanilla sheets).

回答1:

It's easy enough, just loop through the array and count repetitions.

var l = class_names.length, i, tmp = {}, ret = [];
for( i=0; i<l; i++) {
    if( !tmp[class_names[i]]) tmp[class_names[i]] = 0;
    tmp[class_names[i]]++;
}
for( i in tmp) {
    if( tmp.hasOwnProperty(i)) {
        ret.push(i+" "+tmp[i]);
    }
}
// output is ret.join(", ");


回答2:

I think there are many ways to solve your problem...

Possibility A:

  1. If you don't know if the classes are appearing in the right order, try to sort your Array first to ensure that they are grouped properly.
  2. Iterate over the array and count the repetitions, i.e. increase your counter if lastElement === class_names[i] and append the result for the last class name to the result string and set the counter back to 1 otherwise.

Possibility B: Store your Array directly as ["Wizard", 3, "Sorcerer", 2, ...] - this is possible since JS does not require arrays to contain the same type of element at each position.

Possibility C: Use a different structure, e.g. using objects: var class_names = [{name: "Wizard", level: 3}, {name: "Sorcerer", level: 2}, ...]