|
Categorieën >
VB.NET
String.Replace(Array(), Array())
|
|
|
offline
|
   
Grafische Ninja
|
Eentje om uw brein op te breken.
Ik wil de String.Replace functie extenden. .NET heeft geen replace functie voor string array's zoals php dat kan.
Toch komt dit wel eens van pas.
Veel doen dan in .NET:
Dim strTest as String = "ABCDEFG"
MsgBox(strTest.Replace(A,B).Replace(B, C).Replace(C, D).Replace(D, E).Replace(E, F).Replace(F, G).Replace(G, A))
Dim strTest as String = "ABCDEFG" MsgBox(strTest.Replace(A,B).Replace(B, C).Replace(C, D).Replace(D, E).Replace(E, F).Replace(F, G).Replace(G, A))
Maar dit geeft eigenlijk niet het resultaat wat je wil.
Je wil eigenlijk A vervangen door B en B door C en C door D enz.
Niet dat A vervangen wordt door B en dat op z'n beurt dan door C en dan weer naar D.
Want het resultaat van deze MessageBox zal "AAAAAAA" zijn.
Ik wil dus het volgende bereiken:
Dim strTest as String = ABCDEFG
MsgBox(strTest.Replace( _
new Object() { A, B, C, D, E, F, G }, _
new Object() { B, C, D, E, F, G, A } _
)
Dim strTest as String = ABCDEFG MsgBox(strTest.Replace( _ new Object() { A, B, C, D, E, F, G }, _ new Object() { B, C, D, E, F, G, A } _ )
Met als uitkomst : "BCDEFGA"
Hoe zouden jullie hier aan beginnen?
Ik heb al een mogelijk oplossing maar ben er niet 100% tevreden over: http://pastebin.be/23290
Alle ideeën zijn welkom.
het is moeilijker als je initieel denkt |
11 antwoorden
|
|
|
offline
|

Crew .NET
|
Ik heb even iets geprobeerd dat jouw voorbeeld wel doet werken. Als het niet is wat je bedoelt heb ik je verkeerd begrepen of snap ik het niet..
Extension Module
Module Extension
<System.Runtime.CompilerServices.Extension()> _
Public Function Replace(ByVal input As String, ByVal oldValues As String(), ByVal newValues As String()) As String
Dim inputChars As String() = GetStringArray(input)
Dim i As Integer = 0
For Each s As String In inputChars
If oldValues.Contains(s) Then
inputChars(i) = newValues(System.Array.IndexOf(oldValues, s))
End If
i = i + 1
Next
Dim strReturn As String = String.Empty
For Each s As String In inputChars
strReturn &= s
Next
Return strReturn
End Function
Public Function GetStringArray(ByVal input As String) As String()
Dim lstChars As New List(Of String)
For Each c As Char In input.ToCharArray()
lstChars.Add(c.ToString())
Next
Return lstChars.ToArray()
End Function
End Module
Module Extension <System.Runtime.CompilerServices.Extension()> _ Public Function Replace(ByVal input As String, ByVal oldValues As String(), ByVal newValues As String()) As String Dim inputChars As String() = GetStringArray(input) Dim i As Integer = 0 For Each s As String In inputChars If oldValues.Contains(s) Then inputChars(i) = newValues(System.Array.IndexOf(oldValues, s)) End If i = i + 1 Next Dim strReturn As String = String.Empty For Each s As String In inputChars strReturn &= s Next Return strReturn End Function Public Function GetStringArray(ByVal input As String) As String() Dim lstChars As New List(Of String) For Each c As Char In input.ToCharArray() lstChars.Add(c.ToString()) Next Return lstChars.ToArray() End Function End Module
Aanroep
Sub Main()
Dim input As String = "ABCDEFG"
Dim newString As String = input.Replace(New String() {"X", "B", "C", "D", "E", "F", "G"}, New String() {"B", "C", "D", "E", "F", "G", "A"})
Console.WriteLine(newString)
Console.ReadLine()
End Sub
Sub Main() Dim input As String = "ABCDEFG" Dim newString As String = input.Replace(New String() {"X", "B", "C", "D", "E", "F", "G"}, New String() {"B", "C", "D", "E", "F", "G", "A"}) Console.WriteLine(newString) Console.ReadLine() End Sub
|
|
|
|
offline
|
   
Grafische Ninja
|
Dit zal deels werken.
Maar voor bijvoorbeeld:
Sub Main()
Dim input As String = "ABCfooDEFG"
Dim newString As String = input.Replace(New String() {"X", "B", "C", "D", "E", "F", "G", "foo"}, New String() {"B", "C", "D", "E", "F", "G", "A", "bar"})
Console.WriteLine(newString)
Console.ReadLine()
End Sub
Sub Main() Dim input As String = "ABCfooDEFG" Dim newString As String = input.Replace(New String() {"X", "B", "C", "D", "E", "F", "G", "foo"}, New String() {"B", "C", "D", "E", "F", "G", "A", "bar"}) Console.WriteLine(newString) Console.ReadLine() End Sub
Gaat ge nie krijgen: BCDbarEFGA
maar: BCDGooEFGA
|
titjes – 06/02/2010 18:28 (Laatst gewijzigd op 06/02/2010 18:34)
|
|
offline
|

Crew .NET
|
I found it (I guess)  Ik heb het getest met een aantal voorbeelden. Hetgeen jij als eerste gaf en ook met die 'foo' erin. Ook met een string waar er meerdere keren een te vervangen waarde wordt gevonden en dit werkt.
Imports System.Linq
Module Extension
<System.Runtime.CompilerServices.Extension()> _
Public Function Replace(ByVal input As String, ByVal oldValues As String(), ByVal newValues As String()) As String
Dim charDictionary As New SortedDictionary(Of Integer, String)
Dim i As Integer = 0
For Each s As String In oldValues
Dim start As Integer = 0
While input.IndexOf(s, start) > -1
charDictionary.Add(input.IndexOf(s, start), newValues(System.Array.IndexOf(oldValues, s)))
start = start + input.IndexOf(s, start) + s.Length
End While
Next
charDictionary = PrepareDictionary(charDictionary)
Dim indexes As List(Of Integer) = GetUnusedIndexes(input.Length - 1, charDictionary.Keys)
For Each index As Integer In indexes
charDictionary.Add(index, input(index))
Next
Dim returnString As String = String.Empty
For Each key As Integer In charDictionary.Keys
returnString &= charDictionary(key)
Next
Return returnString
End Function
Public Function GetUnusedIndexes(ByVal lastIndexOfInput As Integer, ByVal usedIndexes As SortedDictionary(Of Integer, String).KeyCollection) As List(Of Integer)
Dim lst As New List(Of Integer)
Dim i As Integer
For i = 0 To lastIndexOfInput
If Not usedIndexes.Contains(i) Then
lst.Add(i)
End If
Next
Return lst
End Function
Public Function PrepareDictionary(ByVal dictionary As SortedDictionary(Of Integer, String)) As SortedDictionary(Of Integer, String)
Dim i As Integer
Dim items = From k In dictionary.Values Select k
Dim d As New SortedDictionary(Of Integer, String)
For Each s As String In items.ToList()
Dim index As Integer = (From k In dictionary Where String.Compare(k.Value, s, False).Equals(0) Select k.Key).FirstOrDefault()
For i = 0 To s.Length - 1
d.Add(index + i, s(i))
Next
dictionary.Remove(index)
Next
Return d
End Function
End Module
Imports System.Linq Module Extension <System.Runtime.CompilerServices.Extension()> _ Public Function Replace(ByVal input As String, ByVal oldValues As String(), ByVal newValues As String()) As String Dim charDictionary As New SortedDictionary(Of Integer, String) Dim i As Integer = 0 For Each s As String In oldValues Dim start As Integer = 0 While input.IndexOf(s, start) > -1 charDictionary.Add(input.IndexOf(s, start), newValues(System.Array.IndexOf(oldValues, s))) start = start + input.IndexOf(s, start) + s.Length End While Next charDictionary = PrepareDictionary(charDictionary) Dim indexes As List(Of Integer) = GetUnusedIndexes(input.Length - 1, charDictionary.Keys) For Each index As Integer In indexes charDictionary.Add(index, input(index)) Next Dim returnString As String = String.Empty For Each key As Integer In charDictionary.Keys returnString &= charDictionary(key) Next Return returnString End Function Public Function GetUnusedIndexes(ByVal lastIndexOfInput As Integer, ByVal usedIndexes As SortedDictionary(Of Integer, String).KeyCollection) As List(Of Integer) Dim lst As New List(Of Integer) Dim i As Integer For i = 0 To lastIndexOfInput If Not usedIndexes.Contains(i) Then lst.Add(i) End If Next Return lst End Function Public Function PrepareDictionary (ByVal dictionary As SortedDictionary (Of Integer, String)) As SortedDictionary (Of Integer, String) Dim i As Integer Dim d As New SortedDictionary(Of Integer, String) For Each s As String In items.ToList() Dim index As Integer = (From k In dictionary Where String. Compare(k. Value, s, False). Equals(0) Select k. Key). FirstOrDefault() For i = 0 To s.Length - 1 d.Add(index + i, s(i)) Next Next Return d End Function End Module
|
titjes – 06/02/2010 19:16 (Laatst gewijzigd op 06/02/2010 19:29)
|
|
offline
|

Crew .NET
|
Het projectje want bij mij werkt het perfect!
Edit:
Regel 9 mag weg. (Dim i As Integer = 0)
|
titjes – 06/02/2010 19:57 (Laatst gewijzigd op 08/02/2010 21:31)
|
|
offline
|

Crew .NET
|
Hm, dan is het in de PrepareDictionary bij de Add() nog de juiste index zien te bepalen. Ik zal er nog eens naar kijken.
Edit:
Ik heb er nog eens naar gekeken en normaal moet het nu werken, hoop ik!
Imports System.Linq
Module Extension
<System.Runtime.CompilerServices.Extension()> _
Public Function Replace(ByVal input As String, ByVal oldValues As String(), ByVal newValues As String()) As String
Dim charDictionary As New SortedDictionary(Of Integer, KeyValuePair(Of String, String))
For Each s As String In oldValues
Dim start As Integer = 0
While input.IndexOf(s, start) > -1
charDictionary.Add(input.IndexOf(s, start), New KeyValuePair(Of String, String)(s, newValues(System.Array.IndexOf(oldValues, s))))
start = start + input.IndexOf(s, start) + s.Length
End While
Next
Dim indexes As List(Of Integer) = GetUnusedIndexes(input.Length - 1, charDictionary)
For Each index As Integer In indexes
charDictionary.Add(index, New KeyValuePair(Of String, String)(input(index), input(index)))
Next
Dim finalDictionary As SortedDictionary(Of Integer, String) = PrepareDictionary(charDictionary)
Dim returnString As String = String.Empty
For Each key As Integer In finalDictionary.Keys
returnString &= finalDictionary(key)
Next
Return returnString
End Function
Public Function GetUnusedIndexes(ByVal lastIndexOfInput As Integer, ByVal usedIndexes As SortedDictionary(Of Integer, KeyValuePair(Of String, String))) As List(Of Integer)
Dim lstUnused As New List(Of Integer)
For i As Integer = 0 To lastIndexOfInput
lstUnused.Add(i)
Next
For Each kvp As KeyValuePair(Of Integer, KeyValuePair(Of String, String)) In usedIndexes
For k As Integer = kvp.Key To (kvp.Key + kvp.Value.Key.Length) - 1 Step 1
lstUnused.Remove(k)
Next
Next
Return lstUnused
End Function
Public Function PrepareDictionary(ByVal dictionary As SortedDictionary(Of Integer, KeyValuePair(Of String, String))) As SortedDictionary(Of Integer, String)
Dim d As New SortedDictionary(Of Integer, String)
For Each kvp As KeyValuePair(Of String, String) In (From v In dictionary.Values Select v).ToList()
Dim index As Integer = (From k In dictionary Where String.Compare(k.Value.Value, kvp.Value, False).Equals(0) Select k.Key).FirstOrDefault()
If (d.ContainsKey(index)) Then
index = d.Last().Key + 1
End If
For i As Integer = 0 To kvp.Value.Length - 1
d.Add(index + i, CStr(kvp.Value()(i)))
Next
Next
Return d
End Function
End Module
Imports System.Linq Module Extension <System.Runtime.CompilerServices.Extension()> _ Public Function Replace(ByVal input As String, ByVal oldValues As String(), ByVal newValues As String()) As String Dim charDictionary As New SortedDictionary(Of Integer, KeyValuePair(Of String, String)) For Each s As String In oldValues Dim start As Integer = 0 While input.IndexOf(s, start) > -1 charDictionary.Add(input.IndexOf(s, start), New KeyValuePair(Of String, String)(s, newValues(System.Array.IndexOf(oldValues, s)))) start = start + input.IndexOf(s, start) + s.Length End While Next Dim indexes As List(Of Integer) = GetUnusedIndexes(input.Length - 1, charDictionary) For Each index As Integer In indexes charDictionary.Add(index, New KeyValuePair(Of String, String)(input(index), input(index))) Next Dim finalDictionary As SortedDictionary(Of Integer, String) = PrepareDictionary(charDictionary) Dim returnString As String = String.Empty For Each key As Integer In finalDictionary.Keys returnString &= finalDictionary(key) Next Return returnString End Function Public Function GetUnusedIndexes(ByVal lastIndexOfInput As Integer, ByVal usedIndexes As SortedDictionary(Of Integer, KeyValuePair(Of String, String))) As List(Of Integer) Dim lstUnused As New List(Of Integer) For i As Integer = 0 To lastIndexOfInput lstUnused.Add(i) Next For Each kvp As KeyValuePair(Of Integer, KeyValuePair(Of String, String)) In usedIndexes For k As Integer = kvp.Key To (kvp.Key + kvp.Value.Key.Length) - 1 Step 1 lstUnused.Remove(k) Next Next Return lstUnused End Function Public Function PrepareDictionary (ByVal dictionary As SortedDictionary (Of Integer, KeyValuePair (Of String, String))) As SortedDictionary (Of Integer, String) Dim d As New SortedDictionary(Of Integer, String) For Each kvp As KeyValuePair (Of String, String) In (From v In dictionary. Values Select v ). ToList() Dim index As Integer = (From k In dictionary Where String. Compare(k. Value. Value, kvp. Value, False). Equals(0) Select k. Key). FirstOrDefault() If (d.ContainsKey(index)) Then index = d.Last().Key + 1 End If For i As Integer = 0 To kvp.Value.Length - 1 d.Add(index + i, CStr(kvp.Value()(i))) Next Next Return d End Function End Module
Volgende test werkt in ieder geval:
input = "ABCfooDEFG"
newString = input.Replace(New String() {"A", "B", "C", "D", "E", "F", "G", "foo"}, New String() {"B", "C", "D", "E", "F", "G", "A", "blaat"})
Console.WriteLine(newString)
input = "ABCfooDEFG" newString = input.Replace(New String() {"A", "B", "C", "D", "E", "F", "G", "foo"}, New String() {"B", "C", "D", "E", "F", "G", "A", "blaat"}) Console.WriteLine(newString)
Ook als je dan bijvoorbeeld "foo" door "X" vervangt (vervangwaarde < te vervangen waarde) werkt het.
Edit2:
Vervang regel 12 eens door het volgende:
start = input.IndexOf(s, start) + s.Length
start = input.IndexOf(s, start) + s.Length
Klein foutje dat er nog in zat!
|
|
|
|
offline
|

Crew .NET
|
Inderdaad, ik heb het wel nog een stuk kunnen inkorten. Er was een stuk code dat eigenlijk werk voor niets was. Nu is het toch meer dan 10 regels korter en werkt evengoed!
Imports System.Linq
Module Extension
<System.Runtime.CompilerServices.Extension()> _
Public Function Replace(ByVal input As String, ByVal oldValues As String(), ByVal newValues As String()) As String
Dim charDictionary As New SortedDictionary(Of Integer, KeyValuePair(Of String, String))
For Each s As String In oldValues
Dim start As Integer = 0
While input.IndexOf(s, start) > -1
charDictionary.Add(input.IndexOf(s, start), New KeyValuePair(Of String, String)(s, newValues(System.Array.IndexOf(oldValues, s))))
start = input.IndexOf(s, start) + s.Length
End While
Next
For Each index As Integer In GetUnusedIndexes(input.Length - 1, charDictionary)
charDictionary.Add(index, New KeyValuePair(Of String, String)(input(index), input(index)))
Next
Return PrepareDictionary(charDictionary)
End Function
Public Function GetUnusedIndexes(ByVal lastIndexOfInput As Integer, ByVal usedIndexes As SortedDictionary(Of Integer, KeyValuePair(Of String, String))) As List(Of Integer)
Dim lstUnused As New List(Of Integer)
For i As Integer = 0 To lastIndexOfInput
lstUnused.Add(i)
Next
For Each kvp As KeyValuePair(Of Integer, KeyValuePair(Of String, String)) In usedIndexes
For k As Integer = kvp.Key To (kvp.Key + kvp.Value.Key.Length) - 1 Step 1
lstUnused.Remove(k)
Next
Next
Return lstUnused
End Function
Public Function PrepareDictionary(ByVal dictionary As SortedDictionary(Of Integer, KeyValuePair(Of String, String))) As String
Dim returnString As String = String.Empty
For Each kvp As KeyValuePair(Of String, String) In (From v In dictionary.Values Select v).ToList()
returnString &= kvp.Value
Next
Return returnString
End Function
End Module
Imports System.Linq Module Extension <System.Runtime.CompilerServices.Extension()> _ Public Function Replace(ByVal input As String, ByVal oldValues As String(), ByVal newValues As String()) As String Dim charDictionary As New SortedDictionary(Of Integer, KeyValuePair(Of String, String)) For Each s As String In oldValues Dim start As Integer = 0 While input.IndexOf(s, start) > -1 charDictionary.Add(input.IndexOf(s, start), New KeyValuePair(Of String, String)(s, newValues(System.Array.IndexOf(oldValues, s)))) start = input.IndexOf(s, start) + s.Length End While Next For Each index As Integer In GetUnusedIndexes(input.Length - 1, charDictionary) charDictionary.Add(index, New KeyValuePair(Of String, String)(input(index), input(index))) Next Return PrepareDictionary(charDictionary) End Function Public Function GetUnusedIndexes(ByVal lastIndexOfInput As Integer, ByVal usedIndexes As SortedDictionary(Of Integer, KeyValuePair(Of String, String))) As List(Of Integer) Dim lstUnused As New List(Of Integer) For i As Integer = 0 To lastIndexOfInput lstUnused.Add(i) Next For Each kvp As KeyValuePair(Of Integer, KeyValuePair(Of String, String)) In usedIndexes For k As Integer = kvp.Key To (kvp.Key + kvp.Value.Key.Length) - 1 Step 1 lstUnused.Remove(k) Next Next Return lstUnused End Function Public Function PrepareDictionary (ByVal dictionary As SortedDictionary (Of Integer, KeyValuePair (Of String, String))) As String Dim returnString As String = String.Empty For Each kvp As KeyValuePair (Of String, String) In (From v In dictionary. Values Select v ). ToList() returnString &= kvp.Value Next Return returnString End Function End Module
|
|
|
|
offline
|
   
Grafische Ninja
|
Het werkt eigenlijk nog niet volledig, probeer maar eens:
Dim test As String = "ABCFooCDE12ABC3456BCD"
MsgBox(test.Replace( _
New String() {"12", "E1", "F", "ABC", "Foo", "C", "5", "23"}, _
New String() {"00", "@6", "G", "BCD1", "Bar", "X", "C", "01"}))
Dim test As String = "ABCFooCDE12ABC3456BCD" MsgBox(test.Replace( _ New String() {"12", "E1", "F", "ABC", "Foo", "C", "5", "23"}, _ New String() {"00", "@6", "G", "BCD1", "Bar", "X", "C", "01"}))
|
Dit onderwerp is gesloten.
|
|
|