简体   繁体   中英

VB.NET - Re-Arranging Data In Arrays

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 :

  1. Split the item,
  2. Group the index part by the text part,
  3. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM