Как разобраться в числовых строках как в численных данных?

На самом деле toString() реализация делает соединение с запятыми по умолчанию:

var arr = [ 42, 55 ];
var str1 = arr.toString(); // Gives you "42,55"
var str2 = String(arr); // Ditto

я не знаю, получает ли это мандат спецификацией JS, но это - то, какой большинство в значительной степени все браузеры, кажется, делают.

11
задан Joan Venge 9 August 2009 в 08:35
поделиться

5 ответов

Вы можете импортировать функцию StrCmpLogicalW и использовать ее для сортировки строк. Это та же самая функция, которую сам Explorer использует для имен файлов.

Не поможет вам, если вы не хотите P / Invoke или не хотите поддерживать совместимость с другими системами.

9
ответ дан 3 December 2019 в 01:24
поделиться

Нужно ли мне для этого разбирать строку и преобразовывать ее в число?

По сути, да; но LINQ может помочь:

var sorted = arr.OrderBy(s => int.Parse(s.Substring(5)));
foreach (string s in sorted) {
    Console.WriteLine(s);
}
12
ответ дан 3 December 2019 в 01:24
поделиться

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

public class StringNum : IComparable<StringNum> {

   private List<string> _strings;
   private List<int> _numbers;

   public StringNum(string value) {
      _strings = new List<string>();
      _numbers = new List<int>();
      int pos = 0;
      bool number = false;
      while (pos < value.Length) {
         int len = 0;
         while (pos + len < value.Length && Char.IsDigit(value[pos+len]) == number) {
            len++;
         }
         if (number) {
            _numbers.Add(int.Parse(value.Substring(pos, len)));
         } else {
            _strings.Add(value.Substring(pos, len));
         }
         pos += len;
         number = !number;
      }
   }

   public int CompareTo(StringNum other) {
      int index = 0;
      while (index < _strings.Count && index < other._strings.Count) {
         int result = _strings[index].CompareTo(other._strings[index]);
         if (result != 0) return result;
         if (index < _numbers.Count && index < other._numbers.Count) {
            result = _numbers[index].CompareTo(other._numbers[index]);
            if (result != 0) return result;
         } else {
            return index == _numbers.Count && index == other._numbers.Count ? 0 : index == _numbers.Count ? -1 : 1;
         }
         index++;
      }
      return index == _strings.Count && index == other._strings.Count ? 0 : index == _strings.Count ? -1 : 1;
   }

}

Пример:

List<string> items = new List<string> {
  "item_66b",
  "999",
  "item_5",
  "14",
  "file_14",
  "26",
  "file_2",
  "item_66a",
  "9",
  "file_10",
  "item_1",
  "file_1"
};

items.Sort((a,b)=>new StringNum(a).CompareTo(new StringNum(b)));

foreach (string s in items) Console.WriteLine(s);

Вывод:

9
14
26
999
file_1
file_2
file_10
file_14
item_1
item_5
item_66a
item_66b
10
ответ дан 3 December 2019 в 01:24
поделиться

Простой способ - дополнить числовую часть следующим образом:

file_00001
file_00002
file_00010
file_00011

и т. д.

Но это зависит от знания максимального значения, которое может содержать числовая часть. взять.

2
ответ дан 3 December 2019 в 01:24
поделиться

Некоторое время назад я использовал следующий подход в одном проекте. Это не особенно эффективно, но если количество элементов для сортировки невелико, он работает достаточно хорошо для этого использования. Что он делает, так это то, что он разбивает строки для сравнения на массивы по символу '_' , а затем сравнивает каждый элемент массивов. Предпринята попытка проанализировать последний элемент как int и произвести там числовое сравнение.

Он также имеет ранний выход, если входные строки будут содержать другое количество элементов (поэтому, если вы сравните "file_nbr_1" с " file_23 ", он не будет сравнивать каждую часть строк, а будет просто сравнивать обычные строки на полных строках):

char[] splitChars = new char[] { '_' };
string[] strings = new[] {
    "file_1",
    "file_8",
    "file_11",
    "file_2"
};

Array.Sort(strings, delegate(string x, string y)
{
    // split the strings into arrays on each '_' character
    string[] xValues = x.Split(splitChars);
    string[] yValues = y.Split(splitChars);

    // if the arrays are of different lengths, just 
    //make a regular string comparison on the full values
    if (xValues.Length != yValues.Length)
    {
        return x.CompareTo(y);
    }

    // So, the arrays are of equal length, compare each element
    for (int i = 0; i < xValues.Length; i++)
    {
        if (i == xValues.Length - 1)
        {
            // we are looking at the last element of the arrays

            // first, try to parse the values as ints
            int xInt = 0;
            int yInt = 0;
            if (int.TryParse(xValues[i], out xInt) 
                && int.TryParse(yValues[i], out yInt))
            {
                // if parsing the values as ints was successful 
                // for both values, make a numeric comparison 
                // and return the result
                return xInt.CompareTo(yInt);
            }
        }

        if (string.Compare(xValues[i], yValues[i], 
            StringComparison.InvariantCultureIgnoreCase) != 0)
        {
            break;
        }
    }

    return x.CompareTo(y);

});
2
ответ дан 3 December 2019 в 01:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: