frank wu Ответов: 1

Vb.net как отфильтровать одни и те же элементы в массиве?


Мой массив:

"100#200#0"
"200#120#0"
"100#560#0"
"200#780#0"
"100#-320#0"
"300#980#0"
"400#220#0"
"100#-290#0"
"500#400#0"
"600#450#0"

Результаты:

"100#560#0"
"200#780#0"
"300#980#0"
"400#220#0"
"500#400#0"
"600#450#0"

Что я уже пробовал:

VB.NET как отфильтровать одни и те же элементы в массиве?

Richard MacCutchan

Используйте одну из универсальных коллекций, которая не допускает дубликатов.

Thomas Daniels

Если есть "200#120#0" и "200#780#0", как мы узнаем, какой из них выбрать? Только один из них включен в ваши окончательные результаты, но мы не можем понять, почему.

frank wu

Привет, Фокс


Выберите самый большой, и # 780 # - это число больше нуля.

1 Ответов

Рейтинг:
8

Thomas Daniels

Это можно сделать с помощью методов расширения LINQ:

Dim filtered = array.GroupBy(
    Function(x) x.Split("#")(0)
) _
.Select(
    Function(x)
        Return x.OrderByDescending(Function(y) Int32.Parse(y.Split("#")(1))) _
        .First()
    End Function
).ToArray()

Это длинное заявление! Давайте посмотрим, что он делает:

  1. GroupBy делает то, что говорит вам его название: он "группирует" элементы по определенному условию, которое мы проходим - здесь мы группируем их по x.Split("#")(0), что означает, что первый элемент массива мы получаем, разбивая строку на # (все до первого # char). Результат этого группового вызова будет выглядеть следующим образом:
    Group 0:
    "100#200#0"
    "100#560#0"
    "100#-320#0"
    "100#-290#0"
    
    Group 1:
    "200#120#0"
    "200#780#0"
    
    Group 2:
    "300#980#0"
    
    Group 3:
    "400#220#0"
    
    Group 4:
    "500#400#0"
    
    Group 5:
    "600#450#0"

  2. Для каждой группы нас интересует строка с наибольшим "средним значением". Вот что делает наш оператор select: для каждой группы (из Типа IGrouping [^]), который мы называем x, мы возвращаем одну строку. x.OrderByDescending позволяет нам упорядочить элементы в группе, а ее аргумент позволяет нам решить, как упорядочить. Мы хотим упорядочить по" среднему значению " строку, преобразованную в целое число - вот что Function(y) Int32.Parse(y.Split("#")(1)) делает. Но мы не хотим выбирать всю отсортированную коллекцию, нам нужен только первый элемент: .First().

    Результатом этой функции выбора является:
    "100#560#0"
    "200#780#0"
    "300#980#0"
    "400#220#0"
    "500#400#0"
    "600#450#0"

  3. Возвращаемый тип Select-это IEnumerable (здесь IEnumerable (Of String) потому что он содержит строковые значения), но если вы хотите иметь массив, вы должны позвонить ToArray на нем.


MSDN документация всех функций, которые мы использовали:
Перечислимый.GroupBy(TSource, TKey, TElement) Способ (Интерфейс IEnumerable(Метод), Функция(Метод TKey), Функции(Метода, TElement)) (Системы.В LINQ)[^]
Строка.Метод Разделения (Char []) (System)[^]
Перечислимый.Выберите(Метод TResult), Которой Способ (Интерфейс IEnumerable(Метод), Функция(Метод Становится TResult)) (Системы.В LINQ)[^]
Перечислимый.OrderByDescending(Метод TKey) Способ (Интерфейс IEnumerable(Метод), Функция(Метод TKey)) (Системы.В LINQ)[^]
Int32. Parse Method (String) (System)[^]
Перечислимый.Первый (TSource) Метод (IEnumerable(TSource)) (Системы.В LINQ)[^]
Перечислимый.Метод ToArray(TSource) (IEnumerable(TSource)) (Системы.В LINQ)[^]


frank wu

Привет, Фокс ! большое вам спасибо!

Thomas Daniels

Пожалуйста!

Karthik_Mahalingam

5