[VB.NET] String opbouwen aan de hand van substrings

Pagina: 1
Acties:
  • 187 views sinds 30-01-2008
  • Reageer

  • EmilneM
  • Registratie: December 2001
  • Laatst online: 15-09-2023
Een bepaalde string (sLine) moet binnen VB.NET opgebouwd worden om naar een tekstbestand te worden geschreven.

De string moet bestaan uit een aantal substrings (String1, String2, String3). De positie van de substrings binnen de string wordt bepaald aan de hand van een beginpositie '_BeginPos' en lengte '_Length'.

VB.NET heeft de string.Insert() method. Deze insert op een bepaalde plek in de string. Alles wat achter de insert-positie staat wordt dan echter opgeschoven. Dit is niet de bedoeling omdat de parameters '_BeginPos' voor de substrings mogelijk ook kunnen overlappen

Hoe bouw ik string sLine correct op vanuit een lege string sLine?
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'Declaratie parameters
Dim String1_BeginPos As Integer = 2
Dim String1_Length As Integer = 10
Dim String2_BeginPos As Integer = 15
Dim String2_Length As Integer = 30
Dim String3_BeginPos As Integer = 50
Dim String3_Length As Integer = 10

'Declaratie hoofdstring
Dim sLine As String

'Declaratie substrings
Dim String1 As String = "String1"
Dim String2 As String = "String2"
Dim String3 As String = "String3"

[ Voor 5% gewijzigd door EmilneM op 24-02-2005 11:58 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:24
Kijk eens naar de PadLeft en PadRight member methods van de String class, ik denk dat je daar wel wat kunt mee doen...

https://fgheysels.github.io/


  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

Volgens mij mis ik echt helemaal wat je bedoelt, maar als je string1 wil inserten op positie x en string2 op positie y (met y > x), dan kun je na het inserten van string1 op positie x de positie van de string2 toch bepalen door als positie y + string1.Length() te nemen?

edit:
Misschien is (een voorbeeld van) een concreet toepassingsgebied makkelijk, want het lijkt me dat dit anders kan. En oh ja: gebruik liever een stringbuilder. Deze schijnt veel sneller te zijn dan de 'normale' strings met concatten en dergelijke.

[ Voor 39% gewijzigd door OZ-Gump op 24-02-2005 12:05 ]

My personal website


  • EmilneM
  • Registratie: December 2001
  • Laatst online: 15-09-2023
edit:
Misschien is (een voorbeeld van) een concreet toepassingsgebied makkelijk, want het lijkt me dat dit anders kan. En oh ja: gebruik liever een stringbuilder. Deze schijnt veel sneller te zijn dan de 'normale' strings met concatten en dergelijke.
Het gaat om een exportfunctie. Artikelen uit een tabel 'Artikelen' van een mySQL-database moeten geexporteerd worden naar een .txt-bestand. De plaats van de verschillende attributen van een artikel wordt bepaald aan de hand van parameters 'Beginpositie' en 'Lengte' van elk attribuut.

Voor het schrijven naar een .txt-bestand gebruik ik het StreamWriter-object.

Verwijderd

@OZ-Gump"
OZ-Gump schreef op donderdag 24 februari 2005 @ 12:02:
Misschien is (een voorbeeld van) een concreet toepassingsgebied makkelijk, want het lijkt me dat dit anders kan. En oh ja: gebruik liever een stringbuilder. Deze schijnt veel sneller te zijn dan de 'normale' strings met concatten en dergelijke.
Een Stringbuilder is alleen handiger bij een onbekend aantal concatenations.

@TS:
Met de stringwrite kan je misschien ook gewoon geen writeline, maar ook losse writes. Dan hoef je die sLine niet te concatten, maar schrijf je gewoon de stukjes string1/2/3 weg.
als dat niet volstaat. string1.Substring(int,int) is dan iets voor jou. wel ervoor zorgen dat je twee int (lengte) niet langer is dan de bron-string minus de aantal overgeslagen characters.
en dan dus gewoon:
code:
1
sLine = string1.Substring(1,2) + string2.Substring(3,5) + string3.Substring(1,10)

Waarbij de harde getalletjes corresponderen met de juiste variabelen (evt. dus gecorrigeerd als de lengte niet ok is)

  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

Een Stringbuilder is alleen handiger bij een onbekend aantal concatenations
Het gaat niet om het handiger zijn, het gaat erom dat een stringbuilder significant sneller is. Ik ben een testje aan het schrijven, breng je zo op de hoogte.

edit:
concatten van 1000 strings met een string variabele, 10 keer uitgevoerd: 53 ticks gemiddeld
concatten van 10000 strings met een stringbuilder, 10 keer uitgevoerd: 10 ticks gemiddeld

[ Voor 31% gewijzigd door OZ-Gump op 24-02-2005 14:03 ]

My personal website


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 13-05 21:26

gorgi_19

Kruimeltjes zijn weer op :9

Verwijderd schreef op donderdag 24 februari 2005 @ 13:50:
Een Stringbuilder is alleen handiger bij een onbekend aantal concatenations.
Een stringbuilder wordt meestal gebruikt als er meer dan 5 concatenations zijn :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

Wat doet die stringlengte eigenlijk? Is dat gewoon de maximale lengte?
Zo ja, dan heeft dat niets met de uiteindelijke functie te maken.
Je zorgt dan eerst ervoor dat alle strings de maximale (of kleinere) lengte hebben.

Vervolgens beginnen met een string met de lengte van de positie van de eerste string -1.
Dan steeds een string toevoegen.
De leegte tussen de strings berekenen door de positie van de volgende string en de lengte van de net toegevoegde string.
En de volgende string toevoegen, etc.

Zoiets?
Voor zover ik weet is er in ieder geval geen standaard functie voor.

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:24
OZ-Gump schreef op donderdag 24 februari 2005 @ 13:56:
[...]
Het gaat niet om het handiger zijn, het gaat erom dat een stringbuilder significant sneller is. Ik ben een testje aan het schrijven, breng je zo op de hoogte.
Een stringbuilder is alleen significant sneller als je veel concats moet doen; indien je slechts een klein aantal concats moet doen, kan het zijn dat een stringbuilder trager is: je hebt nl. ook nog een kost om een strinbuilder te creeëren.

https://fgheysels.github.io/


  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

whoami schreef op donderdag 24 februari 2005 @ 14:03:
[...]

Een stringbuilder is alleen significant sneller als je veel concats moet doen; indien je slechts een klein aantal concats moet doen, kan het zijn dat een stringbuilder trager is: je hebt nl. ook nog een kost om een strinbuilder te creeëren.
Eensch, het verschil wordt ook pas merkbaar bij veel concats. Er is mij eens verteld dat string teruggrijpt op een oud type, waardoor het ding trager wordt, terwijl stringbuilder dichter bij .Net staat. Maar, houd me ten goede, dat is mij ook maar verteld/ik heb het ook maar gelezen.

Ik vraag me overigens wel af of de TS er nou uiteindelijk nog uit is gekomen?

My personal website


Verwijderd

Uit de performance boeken van M$Microsoft
This section summarizes recommendations to consider when working with strings:
  • Avoid inefficient string concatenation.
  • Use + when the number of appends is known.
  • Use StringBuilder when the number of appends is unknown.
  • Treat StringBuilder as an accumulator.
  • Use the overloaded Compare method for case insensitive string comparisons.
Use StringBuilder for complex string manipulations and when you need to
concatenate strings multiple times.
C#:
1
2
3
4
5
6
7
8
9
10
// using String and '+' to append
String str = "Some Text";
for ( ... loop several times to build the string ...) {
str = str + " additional text ";
}
// using String and .Append method to append
StringBuilder strBuilder = new StringBuilder("Some Text ");
for ( ... loop several times to build the string ...) {
strBuilder.Append(" additional text ");
}

Use + When the Number of Appends Is Known
If you know the number of appends to be made and you are concatenating the strings
in one shot, prefer the + operator for concatenation.
code:
1
String str = str1+str2+str3;

If you concatenate the strings in a single expression, only one call to String.Concat
needs to be made. It results in no temporary strings (for partial combinations of the
strings to be concatenated).
Note: You should not be using + on strings inside a loop or for multiple iterations. Use StringBuilder
instead.

Use StringBuilder When the Number of Appends Is Unknown
If you do not know the number of appends to be made, which might be the case
when iterating through a loop or building dynamic SQL queries, use the
StringBuilder class as shown in the following code sample.
C#:
1
2
3
4
for (int i=0; i< Results.Count; i++)
{
StringBuilder.Append (Results[i]);
}

Treat StringBuilder as an Accumulator
You can treat StringBuilder as an accumulator or reusable buffer. This helps avoid
the allocations of temporary strings during multiple append iterations. Some of the
scenarios where this helps are as follows:
[list]

Concatenating strings. You should always prefer the following approach to string
concatenation when using StringBuilder.
code:
1
2
3
4
5
StringBuilder sb;
sb.Append(str1);
sb.Append(str2);
//Use the preceding code rather than the following.
sb.Append(str1+str2);

This is because you do not need to make the temporary str1+str2 to append str1
and then str2.

• Concatenating the strings from various functions. An example of this is shown in
the following code sample.
code:
1
2
3
4
StringBuilder sb;
sb.Append(f1(...));
sb.Append(f2(...));
sb.Append(f3(...));

The preceding code snippet results in temporary string allocations for the return
values by the functions f1 (...), f2 (...), f3 (...). You can avoid these temporary
allocations by using the following pattern.
void f1( sb,…);
void f2( sb,…);
void f3( sb,…);
In this case, the StringBuilder instance is directly passed as an input parameter to
the methods. sb.Append is directly called in the function body, which avoids the
allocation of temporary strings.

[ Voor 3% gewijzigd door gorgi_19 op 24-02-2005 14:28 ]


  • EmilneM
  • Registratie: December 2001
  • Laatst online: 15-09-2023
MrSleeves schreef op donderdag 24 februari 2005 @ 14:01:
Wat doet die stringlengte eigenlijk? Is dat gewoon de maximale lengte?
Zo ja, dan heeft dat niets met de uiteindelijke functie te maken.
Je zorgt dan eerst ervoor dat alle strings de maximale (of kleinere) lengte hebben.

Vervolgens beginnen met een string met de lengte van de positie van de eerste string -1.
Dan steeds een string toevoegen.
De leegte tussen de strings berekenen door de positie van de volgende string en de lengte van de net toegevoegde string.
En de volgende string toevoegen, etc.

Zoiets?
Voor zover ik weet is er in ieder geval geen standaard functie voor.
_Length is inderdaad de maximale lengte.

Dit komt wel in de richting van hoe het zou moeten. Echter, String2 kan vóór String1 liggen. De volgorde is dus niet direct vooraf bekend.

  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

EmilneM schreef op donderdag 24 februari 2005 @ 14:27:
[...]

_Length is inderdaad de maximale lengte.

Dit komt wel in de richting van hoe het zou moeten. Echter, String2 kan vóór String1 liggen. De volgorde is dus niet direct vooraf bekend.
Euhm.. als de hele handel uit een database komt, zit het in een DataTable neem ik aan.
Daarmee kan je sorteren.

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • EmilneM
  • Registratie: December 2001
  • Laatst online: 15-09-2023
MrSleeves schreef op donderdag 24 februari 2005 @ 14:40:
[...]

Euhm.. als de hele handel uit een database komt, zit het in een DataTable neem ik aan.
Daarmee kan je sorteren.
De parameters komen inderdaad uit een database.
De row die wordt geselecteerd ziet er bijvoorbeeld als volgt uit:

ArtCode_PosArtCode_LenOmschr_PosOmschr_LenVerkPrijs_PosVerkPrijs_Len
32010050708


Daarnaast zou het in theorie ook kunnen voorkomen dat er overlap plaatsvindt....bijvoorbeeld dat ArtCode een deel is van Omschrijving.

  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

EmilneM schreef op donderdag 24 februari 2005 @ 14:52:
[...]


De parameters komen inderdaad uit een database.
De row die wordt geselecteerd ziet er bijvoorbeeld als volgt uit:

ArtCode_PosArtCode_LenOmschr_PosOmschr_LenVerkPrijs_PosVerkPrijs_Len
32010050708


Daarnaast zou het in theorie ook kunnen voorkomen dat er overlap plaatsvindt....bijvoorbeeld dat ArtCode een deel is van Omschrijving.
Kwestie van rijen dus sorteren op de positie.
Wat doe je bij overlap?
Het makkelijkst is om ze af te kappen op de maximale lengte voordat je ze toevoegd.
(Eventueel haal je er nog wat extra af en voeg je ".." toe ofzo.)

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • EmilneM
  • Registratie: December 2001
  • Laatst online: 15-09-2023
MrSleeves schreef op donderdag 24 februari 2005 @ 15:02:
[...]

Kwestie van rijen dus sorteren op de positie.
Wat doe je bij overlap?
Het makkelijkst is om ze af te kappen op de maximale lengte voordat je ze toevoegd.
(Eventueel haal je er nog wat extra af en voeg je ".." toe ofzo.)
Ik heb het idee dat het nog niet helemaal duidelijk is. Een voorbeeld uit de praktijk:

Tabel 'Artikelen':
ArtIDArtCodeOmschrOmschr2VerkPrijs
1AA-BB-02FietsbandMaat: B19.00
2DD03FietsbelGeluid: Tring!4.00


Tabel 'Parameters':
ArtCode_PosArtCode_LenOmschr_PosOmschr_LenOmschr2_PosOmschr2_LenVerkPrijs_PosVerkPrijs_Len
12021204120619


Voorbeeld output tekstbestand:
code:
1
2
3
4
0         10        20        30        40        50        60
0123456789012345678901234567890123456789012345678901234567890123456789
 AA-BB-02            Fietsband           Maat: B                 19.00
 DD03                Fietsbel            Geluid: Tring!           4.00


Het kan in theorie ook dat de parameters van verschillende attributen elkaar overlappen. Stel:

Tabel 'Parameters':
Omschr_PosOmschr_LenOmschr2_PosOmschr2_Len
2120234


Het tekstbestand ziet er dan als volgt uit:

Voorbeeld output tekstbestand:
code:
1
2
3
4
0         10        20        30        40        50        60
0123456789012345678901234567890123456789012345678901234567890123456789
 AA-BB-02            FiMaatand                                   19.00
 DD03                FiGeluel                                     4.00

  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

EmilneM schreef op donderdag 24 februari 2005 @ 15:34:
[...]

Ik heb het idee dat het nog niet helemaal duidelijk is. Een voorbeeld uit de praktijk:
(...)
Het kan in theorie ook dat de parameters van verschillende attributen elkaar overlappen. Stel:

Tabel 'Parameters':
Omschr_PosOmschr_LenOmschr2_PosOmschr2_Len
2120234


Het tekstbestand ziet er dan als volgt uit:

Voorbeeld output tekstbestand:
code:
1
2
3
4
0         10        20        30        40        50        60
0123456789012345678901234567890123456789012345678901234567890123456789
 AA-BB-02            FiMaatand                                   19.00
 DD03                FiGeluel                                     4.00
Wat is dan de functie van de lengte?
Eigenlijk kan je die net zo goed weglaten en alleen de posities nemen.
De verschillen tussen de posities (-1 voor een spatie) is dan de (maximale) lengte.
Alles langer kap je af.

Verder is Omschr en Omschr2 in dit geval niet echt aan te bevelen.
Want wat nu als er opeens een 3e item komt?
Je kan beter de tabel zo ontwerpen dat je een lijstje krijgt met uitvoer;
Dus een kolom met een regelnummer en een kolom met positie (de lengte vervalt dan).
Vervolgens wil je een regel uitvoeren: filteren op regelnummer en sorteren op positie.

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • EmilneM
  • Registratie: December 2001
  • Laatst online: 15-09-2023
Je kan beter de tabel zo ontwerpen dat je een lijstje krijgt met uitvoer
Ik probeerde het simpel te houden maar de tabel met parameters kan meerdere rijen bevatten. Voor elke leverancier zijn bepaalde parameters van toepassing:

Tabel 'Parameters':
LevIDArtCode_PosArtCode_LenOmschr_PosOmschr_LenVerkPrijs_PosVerkPrijs_Len
11202120619
25161915508


Tabel zo ontwerpen dat het een rij is, is dus geen mogelijkheid.

  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

Euhm..
Tabel met ParameterType
1 ArtCode
2 Omschrijving
3 VerkPrijs

code:
1
2
3
4
5
6
7
8
Parametertabel
LevID Regelnr Positie ParameterType
1       1          1          1
1       1          21        2
1       1          61        3
1       2 ....
2       1          5          1
etc.


En dan een ParamID toevoegen als PK ik wel handig..

Ik neem aan dat LevID voor leverering o.i.d. staat en dat die uit meerdere regels bestaat, maargoed.. je snapt het idee hopelijk.

Als het niet zo kan (om wat voor reden dan ook), zul je de drie typen in de regel met elkaar moeten vergelijken en dan per rij sorteren.

[ Voor 32% gewijzigd door MrSleeves op 24-02-2005 16:10 ]

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • EmilneM
  • Registratie: December 2001
  • Laatst online: 15-09-2023
MrSleeves schreef op donderdag 24 februari 2005 @ 16:06:
Euhm..
Tabel met ParameterType
1 ArtCode
2 Omschrijving
3 VerkPrijs

code:
1
2
3
4
5
6
7
8
Parametertabel
LevID Regelnr Positie ParameterType
1       1          1          1
1       1          21        2
1       1          61        3
1       2 ....
2       1          5          1
etc.


En dan een ParamID toevoegen als PK ik wel handig..

Ik neem aan dat LevID voor leverering o.i.d. staat en dat die uit meerdere regels bestaat, maargoed.. je snapt het idee hopelijk.

Als het niet zo kan (om wat voor reden dan ook), zul je de drie typen in de regel met elkaar moeten vergelijken en dan per rij sorteren.
LevID staat voor Leveranciernummer en die is uiteraard uniek in tabel 'Paramters'.

  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

EmilneM schreef op donderdag 24 februari 2005 @ 16:16:
[...]

LevID staat voor Leveranciernummer en die is uiteraard uniek in tabel 'Paramters'.
Dus per LevID is er maar één regelsoort zeg maar.
Dan zou je Regelnr kunnen laten vervallen.
En LevID niet uniek maken (maar zoals ik hierboven liet zien).
Dus waarschijnlijk krijg je dan veel-op-veel verbindingen, die je weer kan opvangen met een tabel:
Tabel Leverancier met een levID en een omschrijving (ofzo) en een tabel LeverancierRegelInd(eling) (=bovenstaande tabel).

30Drie Web Design & IT Consultancy | Raven Consultancy Services

Pagina: 1