Создание строки из коллекции объектов - PullRequest
2 голосов
/ 04 октября 2010

У меня есть вопрос. У меня есть класс Cars, который мне нужно отобразить в простой строке, если они будут проданы или не основаны на их количестве.

Так вот так:

Public Class Car
    Property Index As Integer
    Property Sell As Boolean
End Class
Public Class Cars
    Property Vehicles As New List(Of Car) From {
                    {New Car With {.Index = 1, .Sell = True}},
                    {New Car With {.Index = 2, .Sell = False}},
                    {New Car With {.Index = 3, .Sell = True}},
                    {New Car With {.Index = 4, .Sell = True}},
                    {New Car With {.Index = 5, .Sell = True}},
                    {New Car With {.Index = 6, .Sell = False}},
                    {New Car With {.Index = 7, .Sell = True}},
                    {New Car With {.Index = 8, .Sell = True}},
                    {New Car With {.Index = 9, .Sell = False}},
                    {New Car With {.Index = 10, .Sell = False}},
                    {New Car With {.Index = 11, .Sell = True}}}
End Class

Я бы хотел отобразить простую строку, подобную этой: Продажа автомобилей: 1, 3-5, 7-8, 11 , основанная на значении .Sell.

Существует ли какая-то эвристика для создания такого типа строк в .NET или это просто набор для / каждого и если / тогда и повторное отображение массивов?

Ответы [ 2 ]

4 голосов
/ 04 октября 2010

LINQ определенно упростит решение. Без LINQ вы могли бы использовать StringBuilder и перебирать список, сравнивая соседние элементы и создавая строку. Это было бы более идеальным, чем повторное создание массивов и тому подобное.

Вот решение LINQ:

Dim query = vehicles.Where(Function(c) c.Sell) _
                    .OrderBy(Function(c) c.Index) _
                    .Select(Function(c, i) New With { .Car = c, .Diff = c.Index - vehicles(i).Index }) _
                    .GroupBy(Function(item) item.Diff) _
                    .Select(Function(item) item.First().Car.Index.ToString() &
                        If(item.Count() > 1, "-" & item.Last().Car.Index.ToString(), ""))

Console.WriteLine("Cars to be sold: " & String.Join(", ", query.ToArray()))

С .NET 4 вы можете прервать вызов ToArray(), поскольку String.Join имеет перегрузку, которая принимает IEnumerable<T>.

Код отфильтровывает автомобили со значением Sell True. Для правильной работы списка важно, чтобы он был в порядке Car.Index, следовательно, OrderBy. Логика определения последовательных элементов состоит в том, чтобы сравнивать соседние элементы и группировать их по разнице их индексов. Если есть разница 1, то они являются соседями. Таким образом, второй Select проецируется в анонимный тип, который хранит Car и Diff на основе текущего индекса минус индекс предыдущего автомобиля. GroupBy группирует все различия вместе. Последний Select строит диапазон. Если Count больше 1, мы ставим тире между первым и последним элементами группы. В противном случае один элемент существует, и мы выбираем его как есть. Наконец, мы используем String.Join для возврата списка значений, разделенных запятыми.

0 голосов
/ 04 октября 2010

Я бы сделал это:

Dim list_sold = Vehicles.Where(Function(x As Car) x.Sell = True)
Dim list_index = list_sold.Select(Function(x As Car) x.Index.ToString())

Console.WriteLine("Cars to be sold: {0}", String.Join(", ", list_index))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...