For each in double list - vb.net

Is it possible to do a for each joining two list and browse through the new "duo list" ?
something like :
For Each elm In list1 Join list2
elm.obj1 // objet with list1 type
elm.obj2 // object with list2 type
next elm
Lists have the same length.

You can join by index with LINQ's Enumerable.Zip and create an anonymous type:
Dim zipped = list1.Zip(list2, Function(obj1, obj2) New With {Key obj1, Key obj2})
For Each pair In zipped
Console.WriteLine(pair.obj1)
Console.WriteLine(pair.obj2)
Next
Note that zipped is not a collection yet but a query. Whenever you will enumerate it(f.e. with For Each, First, ToList etc.) you will execute this query again. If you need to persist it you can create a list or array(ToList/ToArray) and access this instead.
The lazy evaluation of many LINQ methods is called Deferred Execution.

If you mean that you want to enumerate a single, combined list then you would do this:
For Each item In list1.Concat(list2)
'Use item here.
Next
If what you actually mean is that you want to access the items in both lists at the same index at the same time then how would a For Each loop make sense? In that case you'd use a For loop and get both items by index:
For i = 0 To list1.Count - 1
Dim item1 = list1(i)
Dim item2 = list2(i)
'Use item1 and item2 here.
Next
Taking into account the Zip method used in the other answer and combining it with my Tuple suggestion:
For Each tpl In list1.Zip(list2, Function(a, b) AddressOf Tuple.Create)
Console.WriteLine(tpl.Item1)
Console.WriteLine(tpl.Item2)
Next

Related

Populate list box from string on different lines

I have a query that returns a list of items that are in one listbox but not another. I want to put the results of that into a different listbox, problem is that when I try to put the results into a listbox, it puts them all on the same line. Say it returns three results (project_green Project_blue_ project_red), its adding them to one line in the list box as (project_greenproject_blueproject_red). I want each item to be on its own line but I can't get it there.
Here is the code I have
Dim result As List(Of String) = (From s1 As String In Me.ListBox1.Items Where Not Me.ListBox4.Items.Contains(s1) Select s1).ToList()
ListBox5.Items.Add(String.Join(Environment.NewLine, result))
Any help would be appreciated.
Thanks
Dim result = From s1 As String In ListBox1.Items Where Not ListBox4.Items.Contains(s1) Select s1
ListBox5.Items.AddRange(result)
This also saves you a bunch of extra memory. There's no need to allocate a List when the IEnumerable result form the linq query will already do on its own.
Though personally, I'm not a fan of the query comprehension syntax and prefer to write it this way:
Dim result = ListBox1.Items.Where(Function(s1) Not ListBox4.Items.Contains(s1))
ListBox5.Items.AddRange(result)

How to get index with known value as string in arraylist?

I have ArrayList with multi dimensional values in Structure as ArrayList
Structure
(0)=> Mstructure.ABCD
Area (these are value of ABCD)
Name
(1)=> Mstructure.EFGH
Area
Name
I want to know the index of string ABCD.
I tried
Dim myIndex as Integer = Structure.IndexOf("ABCD")
Dim myIndex = Array.IndexOf(Structure.ToArray(), myString)
This returned only -1. I want to get 0 if string is ABCD
EDITED
Structure is defined as ArrayList. I can iterate over it if I use loop e.g
Structure(i).GetType().Name = "ABCD"
I have checked if it exists in the ArrayList
Dim result = Structure.ToArray().Any(Function(x) x.ToString().Contains("ABCD"))
But I want to know the index of the multidimensional ArrayList without looping it. I want to get the index of Mstructure.ABCD. Msttructure.ABCD has values inside it but without knowing those values I want to get the index value.
(0){Mstructure.ABCD}
(1){Mstructure.EFGH}
(2){Mstructure.IJKL}
hhmmm i would use collections instead, or create an object with multi collections to make it easier for me... Have you thought of that?

Create a dictionary out of a list vb.net

i have a list with 2 columns (clm1=StoreID and clmn2=ProductID).
i need to loop through this list and create a dictionary(StoreID , List(of ProductID))
i am using vb.net . can you please help me with the loop i have to make?
The list data is something like
StoreID ProductID
1 234
2 456
1 222
3 768
1 100
9 876
e.t.c.
I assume that your data is stored somewhat like this:
Structure Item
Public StoreID As Integer
Public ProductID As Integer
End Structure
Dim l As List(Of Item)
Then you have two options. The first one is to create the dictionary by hand:
Dim dictionary As New Dictionary(Of Integer, List(Of Integer))
For Each item As Item In l
Dim subList As List(Of Integer)
Dim keyExists = dictionary.TryGetValue(item.StoreID, subList)
If keyExists Then
subList.Add(item.ProductID)
Else
subList = New List(Of Integer)
subList.Add(item.ProductID)
dictionary.Add(item.StoreID, subList)
End If
Next
Here, you just iterate all items. Check the dictionary if it already contains an entry for the store id. If so, just add the product id. If not, create an entry and then add the product id.
If you're not overly concerned with performance, you can use the following LINQ expression to create the dictionary:
Dim dictionary = l.GroupBy(Function(item) item.StoreID) _
.ToDictionary(Function(group) group.Key, _
Function(group) group.Select(Function(item) item.ProductID) _
.ToList())
You first group the elements by their StoreID. Then, the ToDictionary() method creates the dictionary. It takes two parameters. The first one is a function that specifies the key of each element. In this case, we want to use the group's key as the dictionary key (which is the store id). The second parameter is the value that is inserted in the dictionary. First, we use Select to map each Item to its ProductID (because we want to store product ids and not entire items. Then we call ToList() to generate a list from the items in the group.

Remove A Row From A List Of DataRow

I am using a Dictionary to create a key to a List Of DataRow. I want to iterate through each key and remove rows in the List. This will throw an out of range exception when I explicitly try to remove a row. How can I alter my code to accomplish this?
For Each g As KeyValuePair(Of [String], List(Of DataRow)) In grouped
For Each row As DataRow In g.Value
If CInt(segment(1)) <= 4 Then
'THIS THROWS AN OUT OF RANGE EXCEPTION
g.Value.Remove(row)
End If
Next
Next
I only want to remove specific rows based on criteria. Can someone post an example? I am on an old browser the "add comment" function does not work
Can you show a code example of how to use a predicate based on row.Item("ID") with the RemoveAll function?
I tried this and am getting an exception
g.Value.RemoveAll(Function(l) l.Item(Con.ID) Is l.Item(Con.ID).ToString)
Use List.RemoveAll. Not only will this make the act of removing all of the items easier than trying to remove items in some form of looping construct, but it will be dramatically more efficient as the List can reorganize all of the items once at the end, rather than moving the items down one index at a time over and over.
I figured it out using a reverse For loop. I did not see an examlpe on how to use the RemoveAll. Please post an example if you have time
For i As Integer = g.Value.Count - 1 To 0 Step -1
Dim row As DataRow = CType(g.Value(i), DataRow)
Dim segment() As String = row.Item(c._ID).ToString.Split("-"c)
If CInt(segment(1)) <= 4 Then
g.Value.Remove(row)
End If
Next i

VB.net, How to sort collection items by value

How do I sort collection items by value in VB.NET?
I want to sort this:
Dim col as Collection = New Collection
col.Add("b","b1")
col.Add("a","a1")
col.Add("d","d1")
Like #Krishnadditya mentioned, Collections aren't ideal for sorting because they contain items of type Object which is too genereic to be useful in comparing against each other. If you weren't married to a collection, you can do this with a LINQ query to a list or anything that can be cast an enumerable
Dim list = {
New With {.Object = "b", .Key = "b1"},
New With {.Object = "a", .Key = "a1"},
New With {.Object = "d", .Key = "d1"}}
Dim sortedList = _
From item In list
Order By item.Key
As Collection.Add takes general object type and no specific type - sort is not possible. As objects need to be compared against each other to be sort, it will be like comparing oranges and apples.
And Collection provides sorting by Key and not value.
I think, you may have to extend the Collection class and implement the sort. you can move the items by using Insert and RemoveAt methods.
And Just a thought/advice:
if the values are of specific type, how about using some other data structure. Like dictionary for which you can sort by value as mentioned in this link
I decide to use dictionary:
Dim newcol = (From entry In col
Order By entry.Value Descending).ToDictionary(
Function(pair) pair.Key,
Function(pair) pair.Value)