LINQ Sort Numeri c Только данные, но список остается без изменений - PullRequest
4 голосов
/ 02 марта 2020

У меня есть следующая программа. Мои типы данных все строковые. Из списка я хочу отсортировать те записи, которые имеют числовые значения c. Эти записи без числовых данных c всегда будут на последних позициях. Вот мой код Пожалуйста, помогите.

 class Program
{
    static void Main(string[] args)
    {
        var persons = new List<Person>();
        persons.Add(new Person { Name = "John",   Position = "100" });
        persons.Add(new Person { Name = "Peter",  Position = "78"  });
        persons.Add(new Person { Name = "Larry",  Position = "NA"  });
        persons.Add(new Person { Name = "Lovely", Position = ""    });
        persons.Add(new Person { Name = "Rose",   Position = "50"  });
        persons.Add(new Person { Name = "Drew",   Position = "34"  });

        //Help me do the sorting for position that is a number. Priority in sorting are positions which are numbers
        var sortedPersons = persons.OrderBy(x=>double.Parse(x.Position)).ToList();
        foreach (var person in sortedPersons)
            Console.WriteLine("Name: {0}, Position: {1}", person.Name, person.Position);
        Console.ReadLine();
    }
}
public class Person
{
    public string Name { get; set; }
    public string Position { get; set; }
}

Исходя из моего образца, я хочу отсортировать элементы как

  1. Дрю
  2. Роза
  3. Питер
  4. Джон
  5. Прекрасный
  6. Ларри

(для Ловели и Ларри для меня не имеет значения, как они сортируются, пока я сортируюсь правильно Дрю Джону).

Ответы [ 4 ]

7 голосов
/ 02 марта 2020

Попробуйте вместо этого использовать .TryParse() и присвойте максимальное значение чему-либо, что не может быть проанализировано

Вы можете использовать double.MaxValue или double.PositiveInfinity в качестве значения по умолчанию. Последний больше двух.

persons.OrderBy(x => double.TryParse(x.Position, out double d) ? d : double.PositiveInfinity)
3 голосов
/ 02 марта 2020

Вы можете реализовать пользовательский IComparer<string> и передать его экземпляр в качестве второго аргумента методу OrderBy

public class PositionComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        double xValue = int.TryParse(x, out var xParsed) ? xParsed : double.PositiveInfinity;
        double yValue = int.TryParse(y, out var yParsed) ? yParsed : double.PositiveInfinity;

        return xValue.CompareTo(yValue);
    }
}

Пример использования

var sortedPersons = persons.OrderBy(x => x.Position, new PositionComparer()).ToList();

Он обеспечивает правильный вывод и позволяет повторно использовать этот код для сравнения таких значений в других местах.

Name: Drew, Position: 34
Name: Rose, Position: 50
Name: Peter, Position: 78
Name: John, Position: 100
Name: Larry, Position: NA
Name: Lovely, Position:

IMO, его также легче понять, поддерживать и отлаживать, чем Linq методы с разбором логи c внутри

1 голос
/ 02 марта 2020

Если Position должно быть действительным int (скажем, Position = "7.83e+1" считается не цифрой c и должно находиться в конце списка ) мы можем отсортировать по tuple :

  var sortedPersons = persons
    .OrderBy(item => (!int.TryParse(item.Position, out var v), v))
    .ToList();

Здесь мы сначала сортируем по кортежу Item1, который определяет, является ли item.Position int или нет:

!int.TryParse(item.Position, out int v)

поэтому действительные целые числа стоят на первом месте . Затем мы сортируем по кортежу Item2, то есть проанализированное значение

v

, чтобы упорядочить Position s. Если Position должно быть double (скажем, Position = "-7.83e-10" - это совершенно верно ), вы можете использовать Innat3's решение или изменить int на double:

  var sortedPersons = persons
    .OrderBy(item => (!double.TryParse(item.Position, out var v), v))
    .ToList();
0 голосов
/ 02 марта 2020
var sortedPersons = persons.Where(x => int.TryParse(x.Position, out int res))
                           .OrderBy(x => int.Parse(x.Position))
                           .Concat(persons.Where(x => ! int.TryParse(x.Position, out int res)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...