Подтвердить что ты не робот

В JS вы можете полагаться на сравнение строк с операторами ">" и "<"?

Я создаю абстрактную таблицу, каждый столбец в таблице может содержать либо все числа, либо все строки . Каждый столбец должен быть отсортирован, щелкнув заголовок столбца.

В настоящее время я использую родной тип JS и передавая функцию 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 by alphabetical name ----')
console.log(rows)

this.state = {
  sortBy: 'age',
  sortDirection: 'DESC'
}
rows.sort(compareFn)
console.log('---- Sorted by descending age ----')
console.log(rows)
4b9b3361

Ответ 1

Нет, нельзя использовать алфавитную сортировку с помощью операторов >/<. Самый яркий пример того, когда данные не будут правильно отсортированы, - это сочетание символов верхнего и нижнего регистра.

Другие ответы действительны в том, что использование localeCompare - это способ сравнения строк. Тем не менее, я обнаружил, что числа и миксы строк и чисел также можно эффективно сравнивать таким образом.

x.localeCompare(y, 'kn', { numeric: true })

Используя числовую опцию, localeCompare предоставляет мне возможность добиться большей более надежной сортировки, а также избежать необходимости ветвящегося условного логического для обработки каждого случая string и number.

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 by alphabetical name ----')
console.log(rows)

this.state = {
  sortBy: 'age',
  sortDirection: 'DESC'
}
rows.sort(compareFn)
console.log('---- Sorted by descending age ----')
console.log(rows)

this.state = {
  sortBy: 'thing',
  sortDirection: 'ASC'
}
rows.sort(compareFn)
console.log('---- Sorted by ascending thing ----')
console.log(rows)

Ответ 2

Хотя вы можете положиться на сравнение строк с операторами > и <, я бы рекомендовал вам использовать String#localeCompare вместо этого.

Как упоминалось ECMAScript specification, функция localeCompare проверит некоторые проверки перед сравнением строк.

Вы также можете найти больше объяснений в оригинале ECMAScript specification:

Эта функция предназначена для того, чтобы полагаться на любые доступные для языка функции сравнения. в среду ECMAScript из среды хоста и сравнить в соответствии с правилами текущая локальная среда хоста. Настоятельно рекомендуется, чтобы эта функция обрабатывала строки, которые канонически эквивалентны по стандарту Unicode как идентичные (другими словами, сравните строки, как если бы они оба были сначала преобразованы в нормализованную форму C или D).

Обновленный код должен выглядеть следующим образом:

const compareFn = (x, y) => {
  if (this.state.sortDirection === 'DESC') {
    return x[this.state.sortByKey].localeCompare(y[this.state.sortByKey])
  } else {
    return y[this.state.sortByKey].localeCompare(x[this.state.sortByKey])
  }
}
rows.sort(compareFn)

Ответ 3

Я бы сказал, что лучший способ сравнить строки в JS - это метод localeCompare().

first_string.localeCompare(second_string);
/* Expected results:
 0:  exact match
-1:  first_string< second_string
 1:  first_string> second_string
 */

Если вам нужна другая информация, вы должны прочитать некоторые документы here и здесь.


UPDATE

.localeCompare() допускает, что вы можете игнорировать определенные различия в строках (например, puncutation или diacriticals или case) и по-прежнему позволять им сравнивать их, или вы хотите игнорировать определенные различия при выборе какой строки перед другим. И он предоставляет множество опций для контроля того, какие функции сравнения используются или не используются.

Если вы читаете документацию MDN для string.prototype.localeCompare(), вы можете увидеть целую кучу параметров, которые вы можете передать, чтобы указать, как сравните работы. В простой строке ascii без каких-либо специальных символов в этом случае, вы вряд ли увидите разницу, но начнете попадать в диакритические ситуации или проблемы с корпусом, а localCompare() имеет как другие функции, так и больше возможностей для сравнения.

Некоторые параметры, доступные для контроля сравнения: - числовая сортировка - диакритическая чувствительность - способность игнорировать пунктуацию - первый случай - контролировать, будет ли верхний или нижний регистр сначала сравнивать

Morover, localeCompare() возвращает значение (отрицательное, 0 или положительное), которое является perfectly aligned to use with a .sort() обратным вызовом.

Ответ 4

Он будет сравнивать строки, но конкретные значения unicode могут отличаться от предполагаемого поведения. Например, Capital Letters будет иметь меньшее значение, чем строчные, независимо от алфавитного порядка. Если вы будете использовать это, имейте в виду, что порядок {/}/| больше, чем строчная, больше, чем CAPITAL, больше, чем числа, больше, чем большинство символов (! ",).

Ответ 5

Чтобы ответить на ваш вопрос напрямую - да, вы можете полагаться на последовательную сортировку, используя ваш подход. Строки сравниваются на основе стандартного лексикографического упорядочения, используя значения Unicode. См: