Emphram Stavanger
Emphram Stavanger

Reputation: 4214

Sort array of HTML based on output

So I have an array of HTML links;

[
    "<a href=\"...\" target=\"_blank\">foo</a>",
    "<a href=\"...\" target=\"_blank\">apple</a>",
    "<a href=\"...\" target=\"_blank\">cucumber</a>"
]

And I want to sort it based on the user-facing output of it (i.e. the a tag's content);

[
    "<a href=\"...\" target=\"_blank\">apple</a>",
    "<a href=\"...\" target=\"_blank\">cucumber</a>",
    "<a href=\"...\" target=\"_blank\">foo</a>"
]

I imagine I'd have to strip the HTML tags and then .sort() that, but I have no idea how to then reconcile that with the original array. How do I do this?

Upvotes: 0

Views: 70

Answers (3)

adeneo
adeneo

Reputation: 318222

You can use a DOMParser to parse the HTML and get the content of the tags.

By not using a regex, the markup can be anything as long as the selectors match, which is usually what you want as regex isn't really capable of parsing HTML.

Then use localeCompare to compare the strings, this avoids issues with case sensitivity and special characters that you would have with < or >

arr.sort(function(a,b) {
    var docA = new DOMParser().parseFromString(a, "text/html");
    var docB = new DOMParser().parseFromString(b, "text/html");
    var txtA = docA.querySelector('a').innerHTML;
    var txtB = docB.querySelector('a').innerHTML;

    return txtA.localeCompare(txtB);
});

FIDDLE

Upvotes: 5

buff
buff

Reputation: 2053

You pass sortfunction parameter to sort method:

var arr = [
    "<a href=\"...\" target=\"_blank\">foo</a>",
    "<a href=\"...\" target=\"_blank\">apple</a>",
    "<a href=\"...\" target=\"_blank\">cucumber</a>"
];

var sorted = arr.sort(function(a, b) {
    a = strip(a);
    b = strip(b)
    return a.localCompare(b);
}

Here's how you do the strip: Strip HTML from Text JavaScript

Upvotes: 2

Mosho
Mosho

Reputation: 7078

You can use regex and a comparison function to easily do this.

var arr = [
    "<a href=\"...\" target=\"_blank\">foo</a>",
    "<a href=\"...\" target=\"_blank\">apple</a>",
    "<a href=\"...\" target=\"_blank\">cucumber</a>"
]

function compFunc(a,b){
   return a.match(/>(.*)</)[1] > b.match(/>(.*)</)[1];
}

console.log(arr.sort(compFunc))

fiddle

The regex will match anything between the closing > and the following opening < (need to ensure what's between them doesn't contain those chars), and the parentheses around (.*) mean it's a capture group and in the array returned from .match() will have the contents of that capture group (the string we want) as the second element.

Upvotes: 3

Related Questions