How to sort accept more and less than necessary?

I need to have two line sorting to take> and <characters. So, for example, the view may look like

<20 <40 <100 0.1 10 1,000,000.75 >100 >1,000 

So basically all the lines with <first, and then the normal sort, followed by all numbers with the> character. I would also like the sorting to follow the exact order shown (e.g.> 100 appears to> 1000 when sorting from low to high)

Here is my code that works without characters (sorting all rows in a table):

 if ($this.hasClass('sort-mixed')) { sort_func = sort_mixed; } $rows.sort(sort_func); function sort_mixed(a, b) { var val_a = $(a).children().eq(column_index).text(); var val_b = $(b).children().eq(column_index).text(); val_a = Number(val_a.toString().replace(/,/g, "")); val_b = Number(val_b.toString().replace(/,/g, "")); if(val_a > val_b) { return 1 * sort_direction; } if(val_a < val_b) { return -1 * sort_direction; } return 0; } 
+5
source share
3 answers

Sort with a single comparator function:

 var strings = ['0.1', '1,000,000.75', '10', '<100', '<20', '<40', '>1,000', '>100']; var sort = { regular: 1, reverse: -1 }; var sortOrder = sort.regular; function compare(a, b) { function toNum(str) { return +str.replace(/[^0-9.-]/g, ''); } function range(str) { return { '<': -1, '>': 1 }[str[0]] || 0; } var rangeA = range(a); var rangeB = range(b); var score = rangeA === rangeB ? toNum(a) - toNum(b) : rangeA - rangeB; return score * sortOrder; } strings.sort(compare); 

The range() function checks to see if a string starts with '<' or '>' and sets the value that is used for sorting if the strings have different ranges. Otherwise, strings are converted to numbers and simply sorted as numbers.

In the sample input, the resulting array is strings :
["<20", "<40", "<100", "0.1", "10", "1,000,000.75", ">100", ">1,000"]

You can play with him on:
https://jsfiddle.net/eyb7t3jz/8

Edited by:
Added sortOrder .

+1
source

There is no complete solution, but enough to get you started. We split the array into several parts, sort each part, and then merge the array again.

 function toNumber(s) { return +s.replace(/[^0-9.]/g, '') } var arr = [ '<20', '>1,000', '1,000,000.75', '<40', '0.1', '10', '<100', '>100' ]; var lt = arr .filter(s => s.startsWith('<')) .map(s => s.slice(1)) .map(toNumber) .sort((a, b) => a - b) .map(n => '<' + n); var eq = arr .filter(s => !s.startsWith('>') && !s.startsWith('<')) .map(toNumber) .sort((a, b) => a - b) .map(n => '' + n); var gt = arr.filter(s => s.startsWith('>')) .map(s => s.slice(1)) .map(toNumber) .sort((a, b) => a - b) .map(n => '>' + n); console.log([].concat(lt, eq, gt)); 

Outputs:

 ["<20", "<40", "<100", "0.1", "10", "1000000.75", ">100", ">1000"] 
+2
source

Composition approach

 // Sort function maker // - create a sort fn based on two compare fns // {f}= primary // {g}= secondary const sort = (f, g) => (a, b) => f(a,b) || g(a,b) // Compare function maker // - create a compare fn based on a weighting fn, {w} const cmp_asc_of = (w) => (a, b) => w(a) - w(b) const cmp_desc_of = (w) => (a, b) => w(b) - w(a) // Weighting function // - weight a given string, {string}, returns a number const weight_op = (string) => .. const weight_num = (string) => .. // Then, create sort functions const asc = sort(cmp_asc_of(weight_op), cmp_asc_of(weight_num)) const desc = sort(cmp_asc_of(weight_op), cmp_desc_of(weight_num)) // Usage array.sort(asc) array.sort(desc) 

Demo

In your case ..

 .. function sort_mixed(a, b) { var val_a = .. var val_b = .. return isHighToLow ? desc(val_a, val_b) : asc(val_a, val_b) 
0
source

Source: https://habr.com/ru/post/1271408/


All Articles