remove duplicated items with comparing list to another list - vb.net

There are a list1, list2 and list 3.
list 1 contains <british> <electric> <kettle> <and> <bottle> <of> <water>
list 2 contains <british> <electric> <bottle> <water>
the result of list 3 will be <kettle> <and> <of>
As you see, duplicated items has been removed.
Anyone have a code with this?

You can use LINQ:
Dim in1Not2 = list1.Except(list2)
Dim list3 = in1Not2.ToList()
If your list2 also can contain items that are not in list1:
Dim uniqueIn1Or2 = list1.Except(list2).Concat(list2.Except(list1))
Dim list3 = uniqueIn1Or2.ToList()

Related

Randomize strings in a list

Dim myRandom As New Random
Dim myList As New List(Of String)(New String() {"A", "B", "C"})
myList.OrderBy(Function(i) myRandom.Next).ToList()
For k As Integer = 0 To 2
MessageBox.Show(myList.Item(k))
Next
When you run the code, you will see that the MessageBoxes show A,B,C.
I want MessageBoxes show B,C,A or C,B,A or A,C,B or A,B,C or B,A,C or C,A,B according to randomized result.
Note: Using Linq is a must.
The issue is that your code doesn't make any changes to myList. A LINQ query ALWAYS generates a new list. You need to assign the result of ToList back to your myList variable, i.e.
myList = myList.OrderBy(Function(i) myRandom.Next).ToList()

how to check that a list contains another list item in VB.Net

I have two lists like this.
Dim List1 As IList(Of String) = New List(Of String)
Dim ListMatch As IList(Of String) = New List(Of String)
I need to figure out if List1 contains all items of ListMatch. How can i do this is VB.Net?
You can use Not SmallCollection.Except(LargeCollection).Any:
Dim containsAll = Not ListMatch.Except(List1).Any()
Documentation of Enumerable.Except:
This method returns those elements in first that do not appear in
second. It does not also return those elements in second that do not
appear in first.
Since Except is a set method, it doesn't take duplicates into account. So if you also want to know if List1 contains the same count of items of ListMatch you could use(less efficient):
Dim list1Lookup = List1.ToLookup(Function(str) str)
Dim listMatchLookup = ListMatch.ToLookup(Function(str) str)
Dim containsSameCount = listMatchLookup.
All(Function(x) list1Lookup(x.Key).Count() = x.Count())

Comparing three lists

I'm trying to compare three lists and from these lists, trying to find the unique element.
As an example:
List A: 1
List B: 1, 2
List C: 1, 2, 3
As a result, element "3" should be stored.
What I have attempted by looking at previous questions and expanding on is:
Dim result1 As List(Of Long) = A.Except(B).ToList()
Dim result2 As List(Of Long) = C.Except(result1).ToList()
The issue I face is my lists could be as such:
List A: 1
List B: 1
List C: 1, 2
As a result, result1 will store 0 which compares to list C and were then storing in result2: 1 and 2
Is it possible to compare three lists simultaneously? The except document on Microsoft states 2 lists only. Alternatively I could just do a pre check to see if A and B are the same and not to compare them but rather do a 3 way comparison.
How about:
ListA
.Concat(ListB)
.Concat(ListC)
.GroupBy(Function(i) i)
.Where(Function(g) Not g.Skip(1).Any())
.Select(Function(g) g.Key)
There are several ways to do this...
Dim listOfLists = new List(Of List(Of Long))()From { _
listA, _
listB, _
listC _
}
Dim resultList = listOfLists.Aggregate(Function(previousList, nextList) previousList.Intersect(nextList).ToList())
Jon Skeet has another approach, see Intersection of multiple lists with IEnumerable.Intersect() (C#)

Compare 2 ArrayLists and remove duplicates

I am looking to compare values of 2 different ArrayLists, and remove any duplicates from 1 ArrayList.
Example:
Arr1 = {HF,HA,GM,RV}
Arr2 = {FB,HA}
Since they have 'HA' in common, I would like to remove 'HA' from Arr1. Any help or point in the right direction would be appreciated.
You can use LINQ's Except but you will have to convert array lists to regular arrays first:
https://msdn.microsoft.com/en-us/library/bb300779(v=vs.110).aspx
Dim list1 As New ArrayList()
list1.Add("A")
list1.Add("B")
list1.Add("C")
Dim list2 As New ArrayList()
list2.Add("A")
list2.Add("B")
Dim array1 = list1.ToArray()
Dim array2 = list2.ToArray()
Dim except = array1.Except(array2).ToArray()
Also if you need a custom comparison, use this overload instead:
https://msdn.microsoft.com/en-us/library/bb336390(v=vs.110).aspx
EDIT
There are very few LINQ methods available for ArrayList, however you can convert it back very easily:
Dim arrayList as New ArrayList(except)

Associating a list with another that has been sorted

I have two lists, one integer and one string. These values are entered during a loop, so they are associated together (e.g. ListOfInteger.Item(i) and ListOfString.Item(i) were entered at the same time and are related to each other). I sorted and subsequently reversed the list of integers. Is there any way to have the list of strings still associated with the list of integers, in order to display them in a text box. For example:
List of Strings (surname): List of Integers (score):
Jones 4
Perry 2
Morris 6
List of Strings (surname): Sorted List of Integers:
Jones 2
Perry 4
Morris 6
Edit:
If (name.Count + 1) < compnum Then
name.Add(txtName.Text)
score.Add(txtScore.Text)
Else
txtName.Text(Hide)
txtScore.Text(Hide)
btnSort.Text(Show)
End If
...
score.Sort()
score.Reverse()
txtSortedScore1.Text = score(0)
(and so forth)
How can I relate these two lists together in order to associate the data in the string list with the sorted list of integers?
Edit - The end result should look like this:
List of Strings (surname): Sorted List of Integers:
Perry 2
Jones 4
Morris 6
The techniques suggested by the others to use a container class or dictionary are better solutions. However to answer the question as stated, what you seeking to do is perform a keyed sort. Unfortunately, the List(Of T) class does not provide this functionality; it is provided by the Array Class.
This is a bit convoluted as first you dump the two lists to arrays, sort the arrays, and finally recreate the lists with the sorted results.
Dim keysList As List(Of Int32) = New List(Of Integer)(New Int32() {4, 2, 6})
Dim itemsList As List(Of String) = New List(Of String)(New String() {"Jones", "Perry", "Morris"})
Dim keys As Int32() = keysList.ToArray
Dim items As String() = itemsList.ToArray
Array.Sort(keys:=keys, items:=items)
keysList = New List(Of Integer)(keys)
itemsList = New List(Of String)(items)
You should wrap your string and integer in another object.
Class Person
Public String SurName
Public Int Score
End Class
From there you can manipulate your objects in any way you like and then iterate over them and output the data as you like.
Something like this:
Dim persons = New List(Of Person)()
persons.Add(New Person() With { _
Key .SurName = "Jones", _
Key .Score = 4 _
})
For Each p As var In persons.OrderBy(Function(x) x.Score)
ListBox.Add(p.SurName + p.Score)
Next
If you would provide your code, we could help you more.
There are few ways the names can be sorted. Here is one way:
Dim names = {"Jones", "Perry", "Morris"}, score = {4, 2, 6}
Dim sortedIndexes = Enumerable.Range(0, score.Length).OrderBy(Function(i) score(i)).ToArray ' { 1, 0, 2 }
Dim sortedNames = sortedIndexes.Select(Function(i) names(i)).ToList ' { "Perry", "Jones", "Morris" }
Dim sortedScore = sortedIndexes.Select(Function(i) score(i)).ToList ' { 2, 4, 6 }