Click here to Skip to main content
15,923,689 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
My array:

"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"

Results:

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

What I have tried:

VB.NET how to filter out the same elements in the array?
Posted
Updated 3-Aug-17 5:06am
Comments
Richard MacCutchan 3-Aug-17 10:32am    
Use one of the generic collections that does not allow duplicates.
Thomas Daniels 3-Aug-17 10:36am    
If there's "200#120#0" and "200#780#0", how do we know which one to pick? Only one of them is included in your final results, but we can't see why.
frank wu 3-Aug-17 10:39am    
Hi, Fox


Choose the largest one, and # 780 # is a number greater than zero.

1 solution

You can do this using the LINQ extension methods:
VB.NET
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()

That's a long statement! Let's take a look at what it does:

  1. GroupBy does what its name tells you: it 'groups' the elements by a certain condition that we pass - here, we group them by x.Split("#")(0), which means, the first element of the array we get by splitting the string by # (everything before the first # char). The result of this GroupBy call would look like this:
    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. For each group, we are interested in the string with the highest "middle value". That's what our select statement does: for each group (of the IGrouping type[^]), which we call x, we return one string. x.OrderByDescending lets us order the elements in the grouping, and its argument lets us decide how to order. We want to order by the "middle value" of the string converted to an integer - that's what Function(y) Int32.Parse(y.Split("#")(1)) does. But we don't want to select the whole sorted collection, we only want the first element: .First().

    The result of this Select function is:
    "100#560#0"
    "200#780#0"
    "300#980#0"
    "400#220#0"
    "500#400#0"
    "600#450#0"

  3. The return type of Select is an IEnumerable (here an IEnumerable (Of String) because it holds string values), but if you want to have an array, you have to call ToArray on it.


MSDN documentation of all functions we used:
Enumerable.GroupBy(TSource, TKey, TElement) Method (IEnumerable(TSource), Func(TSource, TKey), Func(TSource, TElement)) (System.Linq)[^]
String.Split Method (Char[]) (System)[^]
Enumerable.Select(TSource, TResult) Method (IEnumerable(TSource), Func(TSource, TResult)) (System.Linq)[^]
Enumerable.OrderByDescending(TSource, TKey) Method (IEnumerable(TSource), Func(TSource, TKey)) (System.Linq)[^]
Int32.Parse Method (String) (System)[^]
Enumerable.First(TSource) Method (IEnumerable(TSource)) (System.Linq)[^]
Enumerable.ToArray(TSource) Method (IEnumerable(TSource)) (System.Linq)[^]
 
Share this answer
 
Comments
frank wu 3-Aug-17 11:36am    
Hi ,fox ! thank you so much!
Thomas Daniels 3-Aug-17 11:43am    
You're welcome!
Karthik_Mahalingam 6-Aug-17 23:59pm    
5

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900