javascript - In JS, can you rely on comparing stings with the ">" and "<" operators? -
i building abstract table, each column in table can contain either numbers or strings. each column should sortable clicking on column header.
currently using js native sort , passing comparefunction:
const rows = [ {name: 'adam', age: 27, rank: 3}, {name: 'zeek', age: 31, rank: 1}, {name: 'nancy', age: 45, rank: 4}, {name: 'gramps', age: 102, rank: 2}, ] const comparefn = (x, y) => { const sortdirvalue = this.state.sortdirection === 'desc' ? 1 : -1 if (x[this.state.sortby] === y[this.state.sortby]) return 0 return x[this.state.sortby] < y[this.state.sortby] ? sortdirvalue : -sortdirvalue } this.state = { sortby: 'name', sortdirection: 'asc' } rows.sort(comparefn) console.log('---- sorted alphabetical name ----') console.log(rows) this.state = { sortby: 'age', sortdirection: 'desc' } rows.sort(comparefn) console.log('---- sorted descending age ----') console.log(rows) in test cases i've tried far appears work. however, know js can finicky sorting, how out of box sort() sort arrays of numbers alphabetically.
can rely on consistent correct sorting of both numbers , strings above approach? if not, example of data not sorted way.
no, 1 cannot rely on alphabetical sorting >/< operators. prominent example of when data not sorted way mix of upper , lower case characters.
other answers valid in using localecompare way go comparing strings. however, have found numbers , mixes of strings , numbers can compared way well.
x.localecompare(y, 'kn', { numeric: true }) by utilizing numeric option localecompare provides able achieve more robust sorting, while avoiding needing branching conditional logical handle each string , number case.
const rows = [ {name: 'adam', age: 27, rank: 3, thing: 19}, {name: 'zeek', age: 31, rank: 1, thing: 'wut dis'}, {name: 'nancy', age: 45, rank: 4, thing: '$dolla'}, {name: 'gramps', age: 102, rank: 2, thing: 2}, ] const comparefn = (x, y) => { const xdata = x[this.state.sortby].tostring() const ydata = y[this.state.sortby].tostring() if (this.state.sortdirection !== 'desc') { return xdata.localecompare(ydata, 'kn', { numeric: true }) } else { return ydata.localecompare(xdata, 'kn', { numeric: true }) } } this.state = { sortby: 'name', sortdirection: 'asc' } rows.sort(comparefn) console.log('---- sorted alphabetical name ----') console.log(rows) this.state = { sortby: 'age', sortdirection: 'desc' } rows.sort(comparefn) console.log('---- sorted descending age ----') console.log(rows) this.state = { sortby: 'thing', sortdirection: 'asc' } rows.sort(comparefn) console.log('---- sorted ascending thing ----') console.log(rows)
Comments
Post a Comment