I'm going to try and put this as simply as possible. I have a sentence inputted and I need to "compress" the sentence.
So far in an array I have: "Hello 0" ; "my 1" ; "name 2" ; "is 3" ; "Hello 4" Where the word is the word inputted and the number after is its position.
I need to get it like this: "Hello 0 4" ; "my 1" ; "name 2" ; "is 3"
So basically all the same words fall together in one element of the array with its positions like above.
k = 1
y = 0
For each x in Array
tempArray = x.Split(" ")
tempWord = tempArray(0) 'Takes just word and not position after it
If tempWord = Array(k) Then
newArray(y) = x & Space(1) & tempArray(1) 'tempArray(1) being the position part
y+=1
k+=1
Else
k+=1
End If
Next
This is some code I tried, but to no avail. Any help? Thanks!!
Suggestion: use a Dictionary(Of String, List(of Integer))
. Look at each word and check if it's already in the dictionary. If it's not, then add it to the dictionary with a new empty list instance. In any case should you then add the position to the list of that word in the dictionary.
Once you are done, you can just iterate all KeyValuePairs of the dictionary and append the keys with the associated positions to your result string.
If the order matters (ie if "Hello 0 4" must come first because it was still the first word encountered), you can either note down the order in a separate list whenever you add a new word to the dictionary or you use System.Collections.Specialized.OrderedDictionary
, with the caveat that it's not a generic collection and you have to take care of the typecasting yourself.
Module Module1
Sub Main()
Dim input = {"Hello 0", "my 1", "name 2", "is 3", "Hello 4"}
Dim output As New Dictionary(Of String, String)
For Each current In input
' split current input
Dim currentSplited = current.Split(" ")
Dim word = currentSplited(0)
Dim trailingNumbers = currentSplited(1)
' if it already exists
If output.ContainsKey(word) Then
' add trailing numbers
output(word) = output(word) & " " & trailingNumbers
Else
' new input
output.Add(word, trailingNumbers)
End If
Next
' create new array from dictionary
Dim newArray = output.Select(Function(x) x.Key & " " & x.Value).ToArray()
' print each value in new array
For Each current In newArray
Console.WriteLine(current)
Next
Console.Write("Press any key . . . ")
Console.ReadKey(True)
End Sub
End Module
Here's an answer using Linq which basically works the same as other already pointed :
Join the text and it's group indexes into one string.
' Replace interpolation ($"...") by String.Format if not available Dim output = Aggregate indexedWord In sentence Let parts = indexedWord.Split(" "c) Group parts(1) By word = parts(0) Into indexes = Group Select $"{word} {String.Join(" ", indexes)}" Into ToArray
Here is another inefficient LINQ solution:
Dim myArray = {"Hello 0", "my 1", "name 2", "is 3", "Hello 4"}
Dim grouped = myArray.GroupBy(Function(s) Split(s,, 2)(0), Function(s) Split(s,, 2)(1))
Dim newArray = grouped.Select(Function(g) g.Key & " " & Join(g.ToArray)).ToArray
or with a sentence:
Dim words = "Hello my name is Hello".Split
Dim newArray = Enumerable.Range(0, words.Length).GroupBy(Function(i) words(i),
Function(i) i & "").Select(Function(g) g.Key & " " & Join(g.ToArray)).ToArray
Split(s,, 2)
splits a string by the first space and limits the result to 2 items. If the strings always have only one space then Split(s)
is enough.
The first parameter of the .GroupBy
LINQ extension that I used selects the value to group by, and the second parameter selects the items for each of the groups. For example:
{1,2,2}.GroupBy(Function(i) i)
will result in a collection like this:
.Key items
1 {1}
2 {2,2}
The .Select
LINQ extension is used to convert each group to a string. For example group with .Key
"Hello"
and iems {"0","4"}
will be "Hello" & " " & Join({"0","4"})
and result in "Hello 0 4"
.
The .ToArray
is used to get the IEnumerable
results and store them in an array. For better understanding, I recommend searching for "linq VB" and experiment with some of the examples.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.