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
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 = "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
Abbas - 06/02/2010 18:28 (laatste wijziging 06/02/2010 18:34)
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
Bijna Het moet natuurlijk ook mogelijk zijn om "foo" te vervangen door "vervangstring". Een groter probleem omdat je dan met een onbekend aantal karakters zit te kloten.
Abbas - 06/02/2010 19:57 (laatste wijziging 08/02/2010 21:31)
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
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