Change value of string in a list?
BlitzMax Forums/BlitzMax Programming/Change value of string in a list?
| ||
I can read through a list and cast to whatever I need and change values of other objects, but for some reason I can not change the value of regular string variables in a list:SuperStrict Type TTest Field str:String Field a:Int End Type Local obj:TTest = New TTest Local list:TList = New TList Local myname:String = "Russell" list.AddLast(obj) list.AddLast(myname) For Local a:Object = EachIn list Local temptest:TTest Local tempstring:String If TTest(a) temptest = TTest(a) temptest.str = "Goodbye"' THIS WORKS temptest.a = 10 ' THIS WORKS TOO ElseIf String(a) tempstring = String(a) tempstring = "Jones" ' WHY DOESN'T THIS WORK? EndIf Next I have tried various other methods and none of them change the value of the string. Thanks in advance Russell |
| ||
Works for me but then you don't exactly say what's wrong. |
| ||
If you then go through the list you'll see that the string still equals "Russell", not "Jones" as it should be:For Local a:Object = EachIn list Local temptest:TTest Local tempstring:String If TTest(a) temptest = TTest(a) Print temptest.str ' Print correctly Print temptest.a ' Prints correctly ElseIf String(a) tempstring = String(a) Print tempstring ' Prints "Russell" instead of "Jones" EndIf Next What code are you using to view the list after it is modified? Russell |
| ||
All you're doing there is changing the local string, it shouldn't change the value of the completely different string in the list. for example... local a:int=10 local b:int=0 b=a b=10 would you expect the value of 'a' to be 10? no ;) |
| ||
What I want to be able to do is add various kinds of objects, including strings, to a linked list and then to be able to modify those objects within the list. I modified the TTest object's fields with no problem and it worked exactly as expected, but how do I do the same for the string object that was added? I see what you mean as far as changing the local string, but it actually does change the value of the first list object's fields. Run this and you'll see that the two fields of the obj:TTest object are actually changed: SuperStrict Type TTest Field str:String Field a:Int End Type Local obj:TTest = New TTest Local list:TList = New TList Local myname:String = "Russell" list.AddLast(obj) list.AddLast(myname) For Local a:Object = EachIn list Local temptest:TTest Local tempstring:String If TTest(a) temptest = TTest(a) temptest.str = "Goodbye"' THIS WORKS temptest.a = 10 ' THIS WORKS TOO ElseIf String(a) tempstring = String(a) tempstring = "Jones" ' WHY DOESN'T THIS WORK? EndIf Next For Local a:Object = EachIn list Local temptest:TTest Local tempstring:String If TTest(a) temptest = TTest(a) Print temptest.str ' Print "Goodbye" : correct Print temptest.a ' Prints 10 : correct ElseIf String(a) tempstring = String(a) Print tempstring ' Prints original value "Russell" instead of "Jones" EndIf Next Any ideas on how to change the string object as well? Russell |
| ||
For Local a:Object = EachIn list Local temptest:TTest If TTest(a) temptest = TTest(a) temptest.str = "Goodbye"' THIS WORKS temptest.a = 10 ' THIS WORKS TOO ElseIf String(a) TLink(list.findlink(a))._value = "Jones" EndIf Next Maybe not the fastest of solutions, but I can't think of any other way of doing it. |
| ||
Thanks REDI, at least there IS a way to do it! There MUST be a more efficient way, though. Mark? Brucey? Anyone? Russell |
| ||
|
| ||
There MUST be a more efficient way, though. Either wrap the string in a type or collect your objects within a TMap. |
| ||
@Sledge: Yeah, I thought of that one too (and it works). But I just can't believe that a little 'ol string value can't be changed more efficiently/easily. @Perturbio: Thanks...But YIKES! :) Russell |
| ||
@Perturbio: Thanks...But YIKES! :) I think that's as good as its going to get. |
| ||
@Perturbio: Thanks...But YIKES! :) It isn't really a big step away from using Eachin, you're simply using the same methods it uses but now have access to the link, ideally though, the list would expose the current link in it's enumerator so that you could do something like: For Local o:Object = EachIn list if string(o) then list.enumerator.currentLink.value = "changed value" EndIf Next (The above code would obviously have some issues (i.e. nested EachIn would need more work since the enumerator in this instance would be overwritten)). maybe if you had some way to get the enumerator for the current EachIn scope?: For Local o:Object = EachIn list Local enum:TListEnum = getEachInEnum() if string(o) then enum then enum.currentLink.value = "changed value" EndIf Next |
| ||
What I'm wondering is: If a string is an object, doesn't that object have a field (or method to access that field) that actually stores the value for the string? It's no big deal, really. I was just exploring linked lists and trying some things out and found it weird that it wasn't straightforward. I seem to remember that on the old Blitz Basic 2 (for the Amiga), that linked lists worked on the idea of a "current" link that BB kept track of (no TLinks, etc to be aware of) and that you could access it easily and modify the contents. It's been so long, though, that I don't remember the syntax or even how it worked completely. Anyway, thanks everyone. Russell |
| ||
What I'm wondering is: If a string is an object, doesn't that object have a field (or method to access that field) that actually stores the value for the string? BlitzMax strings are immutable (as in many languages). However, if you don't change the length you *could* write over the memory, but then any copies of that string would also change... Not a good idea. I would just use Remove and Add-methods - the performance effect won't be too much unless you are doing something extreme, in which case Perturbio's code is the way to go. |
| ||
Thanks, everyone. Russell |