Linq - Order by number then letters

前端 未结 2 759
野趣味
野趣味 2020-12-16 03:19

I have a list of strings, and these strings contain numbers and words.

What I wanted to do is order it by the numbers (numeric order) followed by the words (alphabet

相关标签:
2条回答
  • 2020-12-16 03:46

    This solution attempts parsing once for each value.

    List<string> voltage = new List<string>() { "1", "5", "500" , "LT", "RT", "400" };
    
    List<string> result = voltage
      .OrderBy(s =>
      {
        int i = 0;
        return int.TryParse(s, out i) ? i : int.MaxValue;
      })
      .ThenBy(s => s)
      .ToList();
    
    0 讨论(0)
  • 2020-12-16 04:00

    Given that you're doing it all in-process (as you've got a ToList call) I think I'd just use a custom comparer:

    return ActiveRecordLinq.AsQueryable<Equipment>()
                           .Select(x => x.Voltage)
                           .Distinct()
                           .AsEnumerable() // Do the rest in-process
                           .Where(x => !string.IsNullOrEmpty(x))
                           .OrderBy(x => x, new AlphaNumericComparer())
                           .ToList();
    

    Where AlphaNumericComparer implements IComparer<string>, something like this:

    public int Compare(string first, string second)
    {
        // For simplicity, let's assume neither is null :)
    
        int firstNumber, secondNumber;
        bool firstIsNumber = int.TryParse(first, out firstNumber);
        bool secondIsNumber = int.TryParse(second, out secondNumber);
    
        if (firstIsNumber)
        {
            // If they're both numbers, compare them; otherwise first comes first
            return secondIsNumber ? firstNumber.CompareTo(secondNumber) : -1;
        }
        // If second is a number, that should come first; otherwise compare
        // as strings
        return secondIsNumber ? 1 : first.CompareTo(second);
    }
    

    You could use a giant conditional for the latter part:

    public int Compare(string first, string second)
    {
        // For simplicity, let's assume neither is null :)
    
        int firstNumber, secondNumber;
        bool firstIsNumber = int.TryParse(first, out firstNumber);
        bool secondIsNumber = int.TryParse(second, out secondNumber);
    
        return firstIsNumber 
            ? secondIsNumber ? firstNumber.CompareTo(secondNumber) : -1;
            : secondIsNumber ? 1 : first.CompareTo(second);
    }
    

    ... but in this case I don't think I would :)

    0 讨论(0)
提交回复
热议问题