TheSwamp

Code Red => .NET => Topic started by: jcoon on November 28, 2012, 08:26:40 PM

Title: string continuous with delimeter comma like 1,2,3
Post by: jcoon on November 28, 2012, 08:26:40 PM
I'm trying to capture cogo point point number in a continuous list so that I can pass the list to build a point group after I do some tasks with the points.
 like 1,10,333,.... The problem
I tried the join function but it did not generate the continuous string I thought it would produce.  I tried 
strpointnumber & "," strpointnumber but I'm not generation the correct string. it doesn't seem to keep or hold the original values as it goes Thu the next eval of points.

this is what I was trying to use.

looking for hints or links
Dim getpointnumber As Object() = New Object() {}
Dim pointidnumber(0) As Object
pointidnumber(0) = myPoint.PointNumber
Dim strpointnumber As String = CStr(pointidnumber(0))
Dim result As String = String.Join(",", strpointnumber)
ed.WriteMessage(vbCrLf + vbLf & "Point list: " & result)

Thank you
John
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Jeff H on November 28, 2012, 10:42:49 PM
Not quite sure I understand what you mean and what your are trying to do with example but String.Join takes a collection concatenates it adding the seperator.
 
If you are accessing each element in the collection you can use the StringBuilder class
 
Code - Visual Basic: [Select]
  1.         Dim pointArray() As Double = {12, 10, 45, 55.2, 100}
  2.         Dim stringlist As String = String.Join(", ", pointArray)
  3.         Console.WriteLine(stringlist)
  4.  
  5.         Dim pointList As New List(Of Double)
  6.         pointList.AddRange(pointArray)
  7.  
  8.         Dim sb As New StringBuilder
  9.  
  10.         For Each pnt In pointList
  11.             sb.Append(pnt & ", ")
  12.         Next
  13.  
  14.         Console.WriteLine(sb.ToString())
  15.         Console.Read()
  16.  
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Keith™ on November 28, 2012, 10:45:37 PM
There are alot of things going on with your code that can't be determined from your post, some things jump right out that will cause problems and still other things that you could do to resolve the issue you are having. There is also alot of extra code that isn't necessary .. at least it appears unecessary based on the snippet you provided.

Lets start with something simple.

You want to create a continuous string of comma delimited values to use for another purpose.
Question: Do you need X,Y and Z coordinates or just X and Y?

Ok, now, I have noticed that you Dim the variable just prior to setting its value. Unless there is more to your code, when you Dim a variable, if there was a previous incarnation of that variable, its value will be lost. To prevent this, you should Dim the variable outside the loop where you are setting the values to the string.

Great ... now you should have something like this:
Code - Visual Basic: [Select]
  1. Dim result As String
  2. While (gettingValues = True)
  3. Dim pointidnumber(0) As Object
  4. pointidnumber(0) = myPoint.PointNumber
  5. result &= CStr(pointidnumber(0)) & ","
  6. Wend

Notice in the above code that the string result is Dimmed outside the loop where it is being set. This ensures you do not redim the variable and lose its previous value.

This is a good way to handle creating your strings. However, because you need to use this string elsewhere in your code, it makes sense to create a private variable in the class that can hold your string value. This is because your variable result will go out of scope when the function ends.

Lets do this by adding a private variable in the class.
Code - Visual Basic: [Select]
  1. Class myClass
  2.     Private _results As String = ""
  3.  
  4.     'Other code here
  5.  
  6.     Public Sub getPointsFromObject(ByRef myPoint As Object)
  7.         _results &= CStr(myPoint.PointNumber) & ","
  8.     End Sub
  9.  
  10. End Class

Now, you can see in the above code, the point is passed as a reference to the sub, which extracts the points values and appends them to the string (along with a comma)

This may be good enough, but lets make it alot better, perhaps you want to have more control over the point list .. the problem with the point list as it is now, is that you have to remove the final comma when you pass it to your other function. So, lets make a comma delimited string class that you can pass your values into.

Code - Visual Basic: [Select]
  1. Public Class CDFPointsString
  2.     'Initialize private variables
  3.    Private _strCDFString As String = ""  'String is empty in new class
  4.    Private _is3d As Boolean = False      'Class initializes as 2d point string
  5.  
  6.     'Method to return the number of points in the string
  7.    Public Function PointCount() As Long
  8.  
  9.         Dim count As Long = 0
  10.  
  11.         'Note: Arrays are zero based so there are UBound + 1 elements in the array
  12.        If _is3d Then
  13.             'Set count to the number of 3d points in the string
  14.            count = (UBound(Split(_strCDFString, ",")) + 1) / 3
  15.         Else
  16.             'Set count to the number of 2d points in the string
  17.            count = (UBound(Split(_strCDFString, ",")) + 1) / 2
  18.         End If
  19.  
  20.         Return count
  21.  
  22.     End Function
  23.  
  24.     'Method to get string of points
  25.    Public Overrides Function ToString() As String
  26.         'Remove the last comma and return the remainder of the string
  27.        Return _strCDFString = _strCDFString.Remove(_strCDFString.LastIndexOf(","), 1)
  28.     End Function
  29.  
  30.     'Property to get the point type
  31.    Public ReadOnly Property Type() As PointType
  32.         Get
  33.             Return If(_is3d = True, PointType.Point3D, PointType.Point2D)
  34.         End Get
  35.     End Property
  36.  
  37.     'Property to determine if the string is empty
  38.    Public ReadOnly Property IsEmpty() As Boolean
  39.         Get
  40.             Return _is3d = ""
  41.         End Get
  42.     End Property
  43.  
  44.     'Method to add a comma delimited list representing a point to string
  45.    Public Function AddPoint(ByVal PointList As String) As Boolean
  46.         Dim tempArray As Object
  47.         Dim tempString As String = ""
  48.         Dim count As Integer = 0
  49.         Dim rVal As Boolean = False
  50.  
  51.         'Count the points in the list
  52.        tempArray = Split(PointList, ",")
  53.         For X As Integer = 0 To UBound(tempArray)
  54.             If tempArray(X) <> "" Then
  55.                 count += 1
  56.                 'Add the point to the temp string - This effectively removes any errant
  57.                'empty values such as "1,,3" and turns it into "1,3,"
  58.                tempString &= tempArray(X) & ","
  59.             End If
  60.         Next X
  61.  
  62.         'If our point is the same type as being stored in this class, add it to the point list
  63.        'Note that a 2d point list cannot be added to a 3d list and a 3d point list cannot be added to a 2d list
  64.        If ((_is3d = True And count = 3) Or (_is3d = False And count = 2)) Then
  65.             _strCDFString &= tempString
  66.             rVal = True 'The function succeeded
  67.        Else
  68.             rVal = False 'The function failed - mismatched point type
  69.        End If
  70.  
  71.         Return rVal
  72.  
  73.     End Function
  74.  
  75.     'Constructors - Default constructor creates a 2d point list
  76.    Public Sub New()
  77.         _is3d = False
  78.     End Sub
  79.  
  80.     'Pass True to create a 3d point list
  81.    Public Sub New(ByVal is3d As Boolean)
  82.         _is3d = is3d
  83.     End Sub
  84.  
  85.     'Enum for point type in this string
  86.    Enum PointType
  87.         Point2D = 0 'This is a 2d string list
  88.        Point3D     'This is a 3d string list
  89.    End Enum
  90.  
  91. End Class

To use this example class, follow this example:
Code - Visual Basic: [Select]
  1. Private _points As CDFPointsString = New CDFPointsString(False) 'This is a 2d point list change to True for a 3d point list
  2.    Public Sub AddToString(ByRef MyPoint As Object)
  3.         _points.AddPoint(CStr(MyPoint.PointNumber))
  4.         MsgBox("Count: " & vbTab & _points.PointCount.ToString() & vbCrLf & _
  5.                "Type: " & vbTab & [Enum].GetName(GetType(CDFPointsString.PointType), _points.Type()) & vbCrLf & _
  6.                "IsEmpty: " & vbTab & _points.IsEmpty.ToString() & vbCrLf & _
  7.                "Value:" & vbCrLf & _points.ToString()
  8.               )
  9.     End Sub

If you need any more help feel free to ask
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Jeff H on November 28, 2012, 11:40:09 PM
Totally did not think about last comma and with no validating or error handling should have been more along the lines of
Code - Visual Basic: [Select]
  1.  
  2.         Dim comma As String = ", "
  3.         Dim sb As New StringBuilder
  4.         sb.Append(pointArray(0))
  5.         For i = 1 To pointArray.Length - 1
  6.             sb.Append(comma)
  7.             sb.Append(pointArray(i))
  8.         Next
  9.  
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Keith™ on November 28, 2012, 11:47:13 PM
Totally did not think about last comma and with no validating or error handling should have been more along the lines of

I've been going through this project I have inherited and there are so many assumptions and glaring errors that I am beginning to think it was something I wrote ;-)

Now that I have started to find lots of places in code where variables are assumed to have a specifically formatted value or in arrays where the element occasionally contains nothing .. I've started to see inherent problems in everything.

... and just think ... I have over 4000 code files written in VB.Net, C#.Net, Javascript, ASP.Net, HTML, XML, and SQL ... I've only started to scratch the surface .. and the boss wants it done next week ;-)

Go figure
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Jeff H on November 29, 2012, 12:03:47 AM
Totally did not think about last comma and with no validating or error handling should have been more along the lines of

I've been going through this project I have inherited and there are so many assumptions and glaring errors that I am beginning to think it was something I wrote ;)

Now that I have started to find lots of places in code where variables are assumed to have a specifically formatted value or in arrays where the element occasionally contains nothing .. I've started to see inherent problems in everything.

... and just think ... I have over 4000 code files written in VB.Net, C#.Net, Javascript, ASP.Net, HTML, XML, and SQL ... I've only started to scratch the surface .. and the boss wants it done next week ;)

Go figure
I could send you some code files I wrote to make you feel better that your not having to fix them and make the ones you have not look so bad.
 
One last little point about string concatenation. Strings are imutable so concatenating or any other method that modifies a string returns a new string.
 
When you have unknown number of strings to conatenate a StringBuilder (http://msdn.microsoft.com/en-us/library/system.text.stringbuilder(v=VS.100).aspx) object would probably be a better choice.
If you have a fixed number of strings ("n1" & "n2" & "n...") you probably would not get much benefit from StringBuilder because the compiler would see that and probably combine them to keep from allocating memory for each concatenation.

 
 
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Keith™ on November 29, 2012, 12:17:01 AM
I thought about using StringBuilder but decided that I would keep it simple for the OP

I can't imagine that the performance boost by using StringBuilder would be that significant in this example, but I have been known to be wrong before.

the funny thing is, I have went back and looked at some much older code I wrote and can't conceive how it even worked or what the hell I was thinking when I wrote some of it ... oh how things change when we get a little bit of experience writing code.
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Jeff H on November 29, 2012, 01:23:45 AM
What I have recently started focusing on and just starting to scratch the surface is how ineffective, inefficient, time-wasting, biased viewed, uncreative, my habits and methods for learning, thinking and problem solving are.
 
I wish I would have realized this years ago and could have accomplished much more, but all i can do is work on fixing them and replacing bad habitis with good ones.
 
Have been researching and will probably be making some post on what I find helpful.
 
 
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: fixo on November 29, 2012, 02:47:14 AM

John
My 2 c
Code: [Select]
  Public Sub foo()
            Dim numbers() As Integer = New Integer() {0, 1, 2, 3, 4, 5, 6, 7}
            Dim csv As String = ""
            Dim x As Integer = -1
            For Each n In numbers
                csv = csv + Increment(x, x + 1).ToString & ","
            Next
            MsgBox(csv.TrimEnd(","))
        End Sub
        Private Function Increment(Of T)(ByRef target As T, ByVal value As T) As T
            target = value
            Return value
        End Function
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: jcoon on November 29, 2012, 08:25:22 AM
Guys,
Thank you for your help and samples; Dim a variable, if there was a previous incarnation of that variable, its value will be lost. This is exactly what was happening. I’m new to the string builders and append text strings so I’m grateful for the samples. The samples I pasted where to show that I had at least looked at the join string and a few others. I want to try to learn how to work with strings and some of the newer functions to me n VB I am just starting. This is a lot material Keith to digest but I sure I will be able to gain a better understanding after testing these samples.

>You want to create a continuous string of comma delimited values to use for another purpose.
> Question: Do you need X,Y and Z coordinates or just X and Y?

I wanted to collect the point numbers so I could pass them to the civl3d point query to create a pointgoup. The issue I was having was civil 3d provided this StandardPointGroupQuery with  standard.IncludeNumbers that I would collect by windowing a group of points. The problem I was having using  standard.IncludeNumbers was not all items in that selection where needed in the point group. I first needed to run a test to see if the points collected were above a selected civil 3d surface. If they were above the selected surface at the x,y cogo point location then I wanted to collected those point numbers to use in the standard.IncludeNumbers to build the final point group.

Thank you
John Coon
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: TheMaster on November 29, 2012, 10:22:16 PM

Code - Visual Basic: [Select]
  1. Dim result As String
  2. While (gettingValues = True)
  3. Dim pointidnumber(0) As Object
  4. pointidnumber(0) = myPoint.PointNumber
  5. result &= CStr(pointidnumber(0)) & ","
  6. Wend

Notice in the above code that the string result is Dimmed outside the loop where it is being set. This ensures you do not redim the variable and lose its previous value.

This is a good way to handle creating your strings.


You might want to look at the StringBuilder class, which was intended to avoid the issue the code you show above has, which is that every time you concatenate two strings, it requires a reallocation of memory and copying of the existing string, which is precisely the same as using 'Redim Preserve' to add items to an array, one at a time.

One of the very first best-practices often taught in .NET programming classes, is to never iteratively construct strings the way the above code does, because it is horribly slow (compared to using StringBuilder).

In the CDFPointString class you show, it is pretty much the same problem. In that case, you update the string each time an item is added, which requires a memory allocation and copying of the entire contents of the existing string.  That's a lot of work to do each time an item is added, even though the only time the string result is needed, is (presumably) after having added many items.

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() ) );



Title: Re: string continuous with delimeter comma like 1,2,3
Post by: jcoon on November 30, 2012, 09:13:38 AM
TT

Thank you for your comments. All this string building is a lot to take in at first. This weekend I will work on trying to get my arms around this StringBuilder. It looks like a majority of the civil 3D objects requires toString to retrieve data about these object. I do not remember having to do that in VBA.
All I can say is thank you to all for your help. Trying to work on these vb samples is a lot of fun. It is like a 5,000 piece puzzle.

John Coon
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Keith™ on November 30, 2012, 09:58:08 AM
You might want to look at the StringBuilder class, which was intended to avoid the issue the code you show above has, which is that every time you concatenate two strings, it requires a reallocation of memory and copying of the existing string, which is precisely the same as using 'Redim Preserve' to add items to an array, one at a time.

I am quite aware of the requirement to allocate memory when concatenating strings

One of the very first best-practices often taught in .NET programming classes, is to never iteratively construct strings the way the above code does, because it is horribly slow (compared to using StringBuilder).

Slower? yes, Significantly? perhaps, it is all predicated on the number of times the string is modified. In my tests, when six or less modifications are made in sequence, there is no performance boost by using StringBuilder ... in a loop with dozens or perhaps hundreds of changes, then the performance boost is significant.

In the CDFPointString class you show, it is pretty much the same problem. In that case, you update the string each time an item is added, which requires a memory allocation and copying of the entire contents of the existing string.  That's a lot of work to do each time an item is added, even though the only time the string result is needed, is (presumably) after having added many items.

agreed

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() ) );


I've done some research on string concatenation and stringbuilder and found that some compilers build the binaries exactly the same, eliminating the performance hit for string concatenations, although Visual Studios does not.
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: TheMaster on November 30, 2012, 11:10:23 AM

Slower? yes, Significantly? perhaps, it is all predicated on the number of times the string is modified. In my tests, when six or less modifications are made in sequence, there is no performance boost by using StringBuilder ... in a loop with dozens or perhaps hundreds of changes, then the performance boost is significant.


I try to avoid making assumptions about how much data/iterations are involved, and when it comes to something like this, doing it in a way that provides significantly-better performance with higher amounts of data or iterations costs no more than 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 and in a way that will not impose a penalty with higher amounts of data.

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.

Quote
I've done some research on string concatenation and stringbuilder and found that some compilers build the binaries exactly the same, eliminating the performance hit for string concatenations, although Visual Studios does not.

Interesting. What compilers are able to do that?
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: zoltan on November 30, 2012, 11:40:27 AM

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.

Quoting the docs:
Quote
Join(String, Object[]) is a convenience method that lets you concatenate each element in an object array without explicitly converting its elements to strings. The string representation of each object in the array is derived by calling that object's ToString method.
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Keith™ 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
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Kerry 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 ??
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: TheMaster 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.
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: TheMaster 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());
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: gile 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

Title: Re: string continuous with delimeter comma like 1,2,3
Post by: jcoon 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
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: TheMaster 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.  
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Jeff H 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  (http://www.codeproject.com/Articles/406046/Why-strings-are-immutable-and-what-are-the-implica)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.
 
 
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: gile 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.         }
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: Jeff H 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.  
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: gile 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...
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: jcoon 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
Title: Re: string continuous with delimeter comma like 1,2,3
Post by: jcoon 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)