Author Topic: string continuous with delimeter comma like 1,2,3  (Read 7535 times)

0 Members and 1 Guest are viewing this topic.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: string continuous with delimeter comma like 1,2,3
« Reply #15 on: November 30, 2012, 04:54:21 PM »
... doing it incorrectly, so the fact that the performance hit is not significant with a relatively-tiny amount of data/iterations doesn't justify doing it incorrectly, when it can just as easily be done correctly ...

I have to believe that you can't see how one sided your opinion happens to be. I don't think you would be that obtuse on purpose.

I submit that there are certainly better ways to do something, however, just because something is not done in the best way possible, certainly does not mean it is done incorrectly.

If your assertion is correct, and I don't necessarily believe it to be, all compilers should only support the more efficient method.

If you do the research you will find that using StringBuilder in preference to iterative string concatenation is a universally-accepted best practice. If you posted that example on StackOverflow or codeproject, you would get a flood of responses, all basically reiterating the same thing I just pointed out.

Yep, the internet is full of flamers .. I thought we were above that here .. guess not
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: string continuous with delimeter comma like 1,2,3
« Reply #16 on: November 30, 2012, 05:28:36 PM »
< .. >
Yep, the internet is full of flamers .. I thought we were above that here .. guess not

I thought we were too untill I saw that :-D

back to reality :

Keith, have you actually tested the relative performance of repeated string modification against using StringBuilder ??
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

TheMaster

  • Guest
Re: string continuous with delimeter comma like 1,2,3
« Reply #17 on: November 30, 2012, 07:37:29 PM »
... doing it incorrectly, so the fact that the performance hit is not significant with a relatively-tiny amount of data/iterations doesn't justify doing it incorrectly, when it can just as easily be done correctly ...

I have to believe that you can't see how one sided your opinion happens to be. I don't think you would be that obtuse on purpose.


Sorry, I don't agree. IMO, it is most-definitely incorrect to iteratively build strings the way your code shows it done. That opinion is shared by many, who would reiterate what I said about it.

Feel free to visit www.codeproject.com or www.StackOverflow.com, and raise the issue there, and see what happens. And please don't mislabel civilized disagreement over an issue like this as 'flaming'.

Quote
I submit that there are certainly better ways to do something, however, just because something is not done in the best way possible, certainly does not mean it is done incorrectly.

If doing it in the most-efficient way has no cost (e.g., it doesn't complicate code or have any other downside), then there is no legitimate reason to not do it in the most-efficient way. The very purpose of StringBuilder is to allow the programmer to avoid having to write grossly-inefficient code to incrementally construct strings. 

Quote
If your assertion is correct, and I don't necessarily believe it to be, all compilers should only support the more efficient method.

I would still like to know what compilers are able to do that. If the number of iterations of a loop is known at compile-time, then it may be possible, but in most real-world cases the number of loop iterations is not known at compile time, and there is a possiblity that any such optimization could be self-defeating if the number of iterations is relatively-small.

Quote
If you do the research you will find that using StringBuilder in preference to iterative string concatenation is a universally-accepted best practice. If you posted that example on StackOverflow or codeproject, you would get a flood of responses, all basically reiterating the same thing I just pointed out.

Yep, the internet is full of flamers .. I thought we were above that here .. guess not

I wouldn't mislabel pointing out a universally-accepted way of doing something correctly as flaming. In fact, without any flaming, I'd be willing to wager that the opinions you would get at those sites (where quite a few .NET gurus from Microsoft routinely post)  would be unanimously in agreement with what I've said here.
« Last Edit: November 30, 2012, 08:00:04 PM by TT »

TheMaster

  • Guest
Re: string continuous with delimeter comma like 1,2,3
« Reply #18 on: November 30, 2012, 09:02:34 PM »

Lastly, a single line of LINQ would produce the desired result the OP needs, given a sequence of points as input:

This is C#, using an array of int's as input.

Code: [Select]

    int[] array = // given input assigned to an array of int

    // String.Join uses a StringBuilder internally:

    string CDFString = string.Join( ", ", array.Select( i => i.ToString() ) );


Do you really need the LINQ code?  The Join<T>(String, IEnumerable<T>) and Join(String, Object[]) methods should take care of it by calling the ToString method internally.


Absolutely not, but don't take that example too literally.

I wrote it that way to show how one can convert a value that's extracted from each element of a sequence of any kind object to a string with a simple bit of LINQ code.

I used the array of int[] as the source in the example, but in reality it could be an array or sequence of some other kind of object from which an integer was extracted from each element, using Select().

Here is a more realistic example, in line with the OP's application:

Code: [Select]

     // given a sequence of CogoPoint objects:
     IEnumerable<CogoPoint> points = //...

     string CDFPointNumbers =
           string.Join( ",", points.Select( p => p.PointNumber.ToString() ));

Note that in earlier versions of .NET prior to (not sure if it is 3.5 or 4.0), you had to first convert the input sequence to an array, like this:

Code: [Select]
     string.Join( ",", points.Select( p => p.PointNumber.ToString() ).ToArray());
« Last Edit: November 30, 2012, 11:10:10 PM by TT »

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: string continuous with delimeter comma like 1,2,3
« Reply #19 on: December 06, 2012, 11:25:04 AM »
Hi,

Just my 2 cts, a generic extension method.

Code - C#: [Select]
  1.     static class Extensions
  2.     {
  3.         public static string ToDelimitedString<T>(this IEnumerable<T> source, string delimiter)
  4.         {
  5.             StringBuilder sb = new StringBuilder(source.First().ToString());
  6.             return source
  7.                 .Skip(1)
  8.                 .Aggregate(sb, (s, t) => s.Append(delimiter).Append(t))
  9.                 .ToString();
  10.         }
  11.  
  12.         public static string ToCsv<T>(this IEnumerable<T> source)
  13.         {
  14.             return source.ToDelimitedString("'");
  15.         }
  16.     }

Code - vb.net: [Select]
  1. Module extensions
  2.  
  3.     <System.Runtime.CompilerServices.Extension> _
  4.     Public Function ToDelimitedString(Of T)(source As IEnumerable(Of T), delimiter As String) As String
  5.         Dim sb As New StringBuilder(source.First().ToString())
  6.         Return source _
  7.             .Skip(1) _
  8.             .Aggregate(sb, Function(s, x) s.Append(delimiter).Append(x)) _
  9.             .ToString()
  10.     End Function
  11.  
  12.     <System.Runtime.CompilerServices.Extension> _
  13.     Public Function ToCsv(Of T)(source As IEnumerable(Of T))
  14.         Return source.ToDelimitedString(",")
  15.     End Function
  16.  
  17. End Module

« Last Edit: December 06, 2012, 11:37:23 AM by gile »
Speaking English as a French Frog

jcoon

  • Newt
  • Posts: 157
Re: string continuous with delimeter comma like 1,2,3
« Reply #20 on: December 06, 2012, 07:14:22 PM »
gile,

Thanks, I'm still working in this task. I'm trying better understand the cogo point objectid stuff; hopefully that might help with my understand how to generate lists of selected points.

below is what I'm after just with windowed cogopoints that will be passed to the add to new point group after point to surface test.

Thank you,
Dim j As Integer
Dim LAYERNAME As String
LAYERNAME = ""
For j = 0 To ThisDrawing.Layers.Count - 1
LAYERNAME = LAYERNAME & "," & ThisDrawing.Layers.Item(j).Name
Next
MsgBox LAYERNAME



o work on

TheMaster

  • Guest
Re: string continuous with delimeter comma like 1,2,3
« Reply #21 on: December 06, 2012, 07:59:40 PM »
Hi,

Just my 2 cts, a generic extension method.

Code - C#: [Select]
  1.     static class Extensions
  2.     {
  3.         public static string ToDelimitedString<T>(this IEnumerable<T> source, string delimiter)
  4.         {
  5.             StringBuilder sb = new StringBuilder(source.First().ToString());
  6.             return source
  7.                 .Skip(1)
  8.                 .Aggregate(sb, (s, t) => s.Append(delimiter).Append(t))
  9.                 .ToString();
  10.         }
  11.  
  12.         public static string ToCsv<T>(this IEnumerable<T> source)
  13.         {
  14.             return source.ToDelimitedString("'");
  15.         }
  16.     }

Code - vb.net: [Select]
  1. Module extensions
  2.  
  3.     <System.Runtime.CompilerServices.Extension> _
  4.     Public Function ToDelimitedString(Of T)(source As IEnumerable(Of T), delimiter As String) As String
  5.         Dim sb As New StringBuilder(source.First().ToString())
  6.         Return source _
  7.             .Skip(1) _
  8.             .Aggregate(sb, Function(s, x) s.Append(delimiter).Append(x)) _
  9.             .ToString()
  10.     End Function
  11.  
  12.     <System.Runtime.CompilerServices.Extension> _
  13.     Public Function ToCsv(Of T)(source As IEnumerable(Of T))
  14.         Return source.ToDelimitedString(",")
  15.     End Function
  16.  
  17. End Module

Hi Gile.   

Unless I'm missing something, wouldn't the following produce the same result?

Code - C#: [Select]
  1.  
  2.    public static string ToDelimitedString<T>( this IEnumerable<T> source, string separator )
  3.    {
  4.       return string.Join<T>( separator, source );
  5.    }
  6.  
  7.  
« Last Edit: December 06, 2012, 08:10:08 PM by TT »

Jeff H

  • Needs a day job
  • Posts: 6150
Re: string continuous with delimeter comma like 1,2,3
« Reply #22 on: December 06, 2012, 08:05:29 PM »
Hi jcoon,
 
This is a very quick and full of holes but might help up understand a little.
 
A string is just a array of characters, it is a reference type but Microsoft make them immutable so acts like value type.
All the replace, join, remove, etc.... modifiers do not edit the string but take the data needed from current string and return a new string..
You can actually modify a string through reflection, unsafe mode, etc... but is not a good idea because of the intern pool , strings used as keys, and other reasons you can search for.
 
So the for each loop in your method the CLR has to allocate memory for the array to hold the characters then copy the characters over and add new ones.
Which will impact performance and take a look here at this link at the charts in middle of page where the compiler knows the number of iterations and is a literal string is being concatenated and string builder performs much better.
 
So you could think of it like a group of mailboxes or slots. The concatenation method you have the same number of slots as characters. For each concatenation you have to get a new slot for each of new and old character then take all the characters out of the old ones and move them into the new ones. Repeat, repeat,
 
You think of the string builder as it starts off with a certain number of slots, and modifies them or adds new characters to empty slots, when it gets full it goes and gets twice as many slots or some factor, so it does not have to go and get new slots and copy characters over for each expression that adds characters.
 
 

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: string continuous with delimeter comma like 1,2,3
« Reply #23 on: December 07, 2012, 01:19:21 AM »
Hi Gile.   

Unless I'm missing something, wouldn't the following produce the same result?

Code - C#: [Select]
  1.  
  2.    public static string ToDelimitedString<T>( this IEnumerable<T> source, string separator )
  3.    {
  4.       return string.Join<T>( separator, source );
  5.    }
  6.  
  7.  

It seems to me that string.Join() cannot be generic and requieres a string array as argument.
It may be like this, (very close to what you posted in your first reply)

Code - C#: [Select]
  1.         public static string ToDelimitedString<T>(this IEnumerable<T> source, string separator)
  2.         {
  3.             return string.Join(separator, source.Select(x => x.ToString()).ToArray());
  4.         }
Speaking English as a French Frog

Jeff H

  • Needs a day job
  • Posts: 6150
Re: string continuous with delimeter comma like 1,2,3
« Reply #24 on: December 07, 2012, 01:44:22 AM »
....
Code - C#: [Select]
  1.  
  2.  [ComVisible(false), __DynamicallyInvokable]
  3. public static string Join<T>(string separator, IEnumerable<T> values)
  4. {
  5.     if (values == null)
  6.     {
  7.         throw new ArgumentNullException("values");
  8.     }
  9.     if (separator == null)
  10.     {
  11.         separator = Empty;
  12.     }
  13.     using (IEnumerator<T> enumerator = values.GetEnumerator())
  14.     {
  15.         if (!enumerator.MoveNext())
  16.         {
  17.             return Empty;
  18.         }
  19.         StringBuilder sb = StringBuilderCache.Acquire(0x10);
  20.         if (enumerator.Current != null)
  21.         {
  22.             string str = enumerator.Current.ToString();
  23.             if (str != null)
  24.             {
  25.                 sb.Append(str);
  26.             }
  27.         }
  28.         while (enumerator.MoveNext())
  29.         {
  30.             sb.Append(separator);
  31.             if (enumerator.Current != null)
  32.             {
  33.                 string str2 = enumerator.Current.ToString();
  34.                 if (str2 != null)
  35.                 {
  36.                     sb.Append(str2);
  37.                 }
  38.             }
  39.         }
  40.         return StringBuilderCache.GetStringAndRelease(sb);
  41.     }
  42. }
  43.  
  44.  
  45.  

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: string continuous with delimeter comma like 1,2,3
« Reply #25 on: December 07, 2012, 02:13:29 AM »
Ok,

Thanks Tony and Jeff, I was targeting NET Framework 3.5 so I didn't see it...
Speaking English as a French Frog

jcoon

  • Newt
  • Posts: 157
Re: string continuous with delimeter comma like 1,2,3
« Reply #26 on: December 08, 2012, 12:32:09 PM »
Moving from vba to VB is going to take even longer than I thought, understanding the relation between the objectid and the civil object properties and converting them to strings might be over my head at this point. I think I'M GOING to just work at learning how to access these civil objects until I'm com forable
with that before I move forward. I want to thank all for the help you provided. If I can't move on after that I think I'll have to have my firm pay to convert my old vba routine to vb. With vba, seemed fairly simple to get going with civil object; with VB it seems to me that you need to have a better understanding to the type of objects being used. everything has a objectid that needs to be converted to something else to be used..........it's confusing at this point but hopefully after working with the basics I'll be able to convert my old apps.

Again thank you all for the help you provided

john

jcoon

  • Newt
  • Posts: 157
Re: string continuous with delimeter comma like 1,2,3
« Reply #27 on: December 10, 2012, 05:49:52 PM »
I was finally able to get the selected point numbers into a continuous string that I passed to the create point group by numbers after running a test on the selected points. I was not aware of the differences with strings. "immutable" and Friend's of and hidden by, Well after reading a few stringbulder links I was able to get this to work.

Thanks for putting up with people like me just getting started.
john


Dim strbuilder As StringBuilder = New StringBuilder()
strPointNumber = myPoint.PointNumber.ToString()
vals.Add(strPointNumber)
Dim value As String = String.Join(",", vals)
strbuilder.Append(vals).Append(",")
ed.WriteMessage(vbCrLf + vbLf & "- point numbers: " & (value)