| View previous topic :: View next topic |
| Author |
Message |
raider2k Op
Joined: 01 Jan 2008 Posts: 140
|
Posted: Mon Apr 13, 2009 6:16 pm Post subject: [SOLVED] join? |
|
|
hi guys ^^
this time im asking about how to make various elements join a list. here it goes:
im reading things from a database which will be handeled with foreach so i can treat each and single element, but thats the "problem" if i can call it like that. things get treated as single elements. example:
i read nicknames from the database and get
john
miles
henry
ashton
and get them as element $nickn in example but want them to be displayed in one single line like here:
john, miles, henry, ashton
i played a bit with join but i wasnt able to find out how to get it into one single line. please help 
Last edited by raider2k on Tue Apr 14, 2009 8:10 am; edited 1 time in total |
|
| Back to top |
|
 |
arfer Master

Joined: 26 Nov 2004 Posts: 436 Location: Manchester, UK
|
Posted: Tue Apr 14, 2009 5:43 am Post subject: |
|
|
It isn't exactly clear where the nicks are coming from. However, the following should help. Your original format of nicks appears to be seperated by newline, as could be the case in a text file.
| Code: |
# read a text file and create an array from the contents
# each line of the text file consists of a unique nick followed by data associated with that nick
proc readFile {} {
# the array will be given global scope so that it can be used elsewhere
global dataArray
# open datafile for reading
# create a list by splitting the file's contents at each newline character
# ignore any newline character after the last line
set id [open db.txt r]
set dataList [split [read -nonewline $id] \n]
close $id
# if dataList created above is not empty, populate dataArray
# first word of each dataList element is a nick and will become the array name
# remainder of each dataList element will become the array value
if {[llength $dataList] != 0} {
foreach line $dataList {
set dataArray([lindex $line 0]) [join [lrange $line 1 end]]
}
}
return 0
}
# create a string variable of comma-space delimited nicks from the element names of an array
proc listNicks {} {
global dataArray
# if dataArray is not empty, create a nickList from the names of it's elements
# convert the nickList to a nickString by joining with comma-space delimiter
# return the nickString to the calling proc
# zero (0) will be returned to the calling proc if dataArray is empty
if {[array size dataArray] != 0} {
set nickList [array names dataArray]
set nickString [join $nickList ", "]
return $nickString
}
return 0
}
|
To generalise, if you have a list and want to create a string, the core Tcl 'join' command is used.
join <list> ?joinString?
Without a joinString specified, a space character is used.
It is very important that you understand (in the context of Tcl) the format of what you are starting with and the format of what you wish to end up with. For example, the code pasted above might return :-
arfer, hernick, hisnick, anothernick
It looks like a list and might be referred to in plain English as a list. In Tcl it could not be treated as a list of nicks. It is a comma-space delimited string of nicks. My advise would be to keep the unique nicks in a list so that you always know what you are dealing with programmatically and only convert to a string if and when you want to output :-
| Code: |
putserv "PRIVMSG #channelname :[join $nickList ", "]
|
_________________ I must have had nothing to do |
|
| Back to top |
|
 |
raider2k Op
Joined: 01 Jan 2008 Posts: 140
|
Posted: Tue Apr 14, 2009 7:11 am Post subject: |
|
|
hmm ...
i might not have understood what you were trying to explain.
lets explain from my point of view how i tried to make it work:
| Code: |
set dbquery [::mysql::sel $db "SELECT `nick` FROM `nicktable`;" -list]
if {![string equal $dbquery ""]} {
foreach name $dbquery {
set user [lindex $name 0]
putserv "PRIVMSG $chan :username: $user"
}
}
|
if i run this code - as i usually do - the output will be:
| Quote: | username: john
username: miles
username: henry
username: ashton |
but i want it to be like this:
| Quote: | | usernames: john - miles - henry - ashton |
regardless of the character being used to separate single outputs (- in this case)
as i said in my last post, i tried to use the join command as in
| Code: |
set newnames ""
set newnames2 [join $newnames " "]
|
as well as
| Code: |
set newnames ""
set newnames2 [join $newnames]
|
as i dont know how to handle the join command exactly |
|
| Back to top |
|
 |
arfer Master

Joined: 26 Nov 2004 Posts: 436 Location: Manchester, UK
|
Posted: Tue Apr 14, 2009 7:28 am Post subject: |
|
|
| Code: |
set dbquery [::mysql::sel $db "SELECT `nick` FROM `nicktable`;" -list]
if {![string equal $dbquery ""]} {
foreach name $dbquery {
lappend users [lindex $name 0]
}
putserv "PRIVMSG $chan :usernames: [join $users ", "]
}
|
I am not familiar with SQL in Tcl but it looks like the query simply returns a list of nicks, in which case the following may be fine :-
| Code: |
set dbquery [::mysql::sel $db "SELECT `nick` FROM `nicktable`;" -list]
if {![string equal $dbquery ""]} {
putserv "PRIVMSG $chan :usernames: [join $dbquery ", "]
}
|
_________________ I must have had nothing to do |
|
| Back to top |
|
 |
raider2k Op
Joined: 01 Jan 2008 Posts: 140
|
Posted: Tue Apr 14, 2009 7:52 am Post subject: |
|
|
mhm ok
and if i want to have - or | or any other separating char i just need to put
| Code: | | [join $dbquery " - "] |
in example, right?
ill try your given example when im at home and hopefully manage to make it work  |
|
| Back to top |
|
 |
raider2k Op
Joined: 01 Jan 2008 Posts: 140
|
Posted: Tue Apr 14, 2009 8:09 am Post subject: |
|
|
| arfer wrote: | | Code: |
set dbquery [::mysql::sel $db "SELECT `nick` FROM `nicktable`;" -list]
if {![string equal $dbquery ""]} {
foreach name $dbquery {
lappend users [lindex $name 0]
}
putserv "PRIVMSG $chan :usernames: [join $users ", "]
}
|
|
outstanding - this one works flawlessly
i didnt know about the power of lappend
thank you very much for your appreciated help ^^ |
|
| Back to top |
|
 |
arfer Master

Joined: 26 Nov 2004 Posts: 436 Location: Manchester, UK
|
Posted: Tue Apr 14, 2009 9:47 am Post subject: |
|
|
The join command takes a string argument, rather than a character or sequence of characters as in the split command.
Your example of [join $string " - "] therefore forms a space-hyphen-space delimited string from a list.
Be very careful with any such code because the split command does not work exactly like this in reverse, in case you want to recreate a list.
Consider the following :-
[14:41] <@arfer> % set y [join {one-penny two three}]
[14:41] <@Baal> one-penny two three
[14:41] <@arfer> % set z [split $y " - "]
[14:41] <@Baal> one penny two three
When I recreated the list, I might have expected to get back to {one-penny two three}. That didn't exactly happen for reasons I have explained above.
There are perhaps two distincly different things to consider. How to hold data such that it is easy to manipulate programmatically and, quite seperately, how you want the data to be seen when output. _________________ I must have had nothing to do |
|
| Back to top |
|
 |
raider2k Op
Joined: 01 Jan 2008 Posts: 140
|
Posted: Tue Apr 14, 2009 10:08 am Post subject: |
|
|
| thanks for your "warnings" but i dont think im going to run into such problems (if you can call them as such) at all. IF i like to use join then only because i want single list elements not to be listed as single elements line for line - i want them to be listed in one long line as good and as long as possible ^^ |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Thu Apr 16, 2009 3:51 pm Post subject: |
|
|
Since you only select one field from your database table, consider using -flatlist instead of list. Saves you the hazzle of creating a new list...
| Code: | set dbquery [::mysql::sel $db "SELECT `nick` FROM `nicktable`;" -flatlist]
if {![string equal $dbquery ""]} {
putserv "PRIVMSG $chan :usernames: [join $dbquery ", "]
} |
_________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
|