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

0 Members and 1 Guest are viewing this topic.

jcoon

  • Newt
  • Posts: 157
string continuous with delimeter comma like 1,2,3
« 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

Jeff H

  • Needs a day job
  • Posts: 6144
Re: string continuous with delimeter comma like 1,2,3
« Reply #1 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.  

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: string continuous with delimeter comma like 1,2,3
« Reply #2 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
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

Jeff H

  • Needs a day job
  • Posts: 6144
Re: string continuous with delimeter comma like 1,2,3
« Reply #3 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.  

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: string continuous with delimeter comma like 1,2,3
« Reply #4 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
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

Jeff H

  • Needs a day job
  • Posts: 6144
Re: string continuous with delimeter comma like 1,2,3
« Reply #5 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 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.

 
 

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: string continuous with delimeter comma like 1,2,3
« Reply #6 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.
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

Jeff H

  • Needs a day job
  • Posts: 6144
Re: string continuous with delimeter comma like 1,2,3
« Reply #7 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.
 
 

fixo

  • Guest
Re: string continuous with delimeter comma like 1,2,3
« Reply #8 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

jcoon

  • Newt
  • Posts: 157
Re: string continuous with delimeter comma like 1,2,3
« Reply #9 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

TheMaster

  • Guest
Re: string continuous with delimeter comma like 1,2,3
« Reply #10 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() ) );



« Last Edit: November 29, 2012, 11:18:50 PM by TT »

jcoon

  • Newt
  • Posts: 157
Re: string continuous with delimeter comma like 1,2,3
« Reply #11 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

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: string continuous with delimeter comma like 1,2,3
« Reply #12 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.
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

TheMaster

  • Guest
Re: string continuous with delimeter comma like 1,2,3
« Reply #13 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?
« Last Edit: November 30, 2012, 11:38:15 AM by TT »

zoltan

  • Guest
Re: string continuous with delimeter comma like 1,2,3
« Reply #14 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.