egghelp.org community Forum Index
[ egghelp.org home | forum home ]
egghelp.org community
Discussion of eggdrop bots, shell accounts and tcl scripts.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[SOLVED] join?

 
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help
View previous topic :: View next topic  
Author Message
raider2k
Op


Joined: 01 Jan 2008
Posts: 140

PostPosted: Mon Apr 13, 2009 6:16 pm    Post subject: [SOLVED] join? Reply with quote

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 Smile


Last edited by raider2k on Tue Apr 14, 2009 8:10 am; edited 1 time in total
Back to top
View user's profile Send private message
arfer
Master


Joined: 26 Nov 2004
Posts: 436
Location: Manchester, UK

PostPosted: Tue Apr 14, 2009 5:43 am    Post subject: Reply with quote

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
View user's profile Send private message
raider2k
Op


Joined: 01 Jan 2008
Posts: 140

PostPosted: Tue Apr 14, 2009 7:11 am    Post subject: Reply with quote

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
View user's profile Send private message
arfer
Master


Joined: 26 Nov 2004
Posts: 436
Location: Manchester, UK

PostPosted: Tue Apr 14, 2009 7:28 am    Post subject: Reply with quote

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
View user's profile Send private message
raider2k
Op


Joined: 01 Jan 2008
Posts: 140

PostPosted: Tue Apr 14, 2009 7:52 am    Post subject: Reply with quote

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 Wink
Back to top
View user's profile Send private message
raider2k
Op


Joined: 01 Jan 2008
Posts: 140

PostPosted: Tue Apr 14, 2009 8:09 am    Post subject: Reply with quote

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 Very Happy
i didnt know about the power of lappend

thank you very much for your appreciated help ^^
Back to top
View user's profile Send private message
arfer
Master


Joined: 26 Nov 2004
Posts: 436
Location: Manchester, UK

PostPosted: Tue Apr 14, 2009 9:47 am    Post subject: Reply with quote

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
View user's profile Send private message
raider2k
Op


Joined: 01 Jan 2008
Posts: 140

PostPosted: Tue Apr 14, 2009 10:08 am    Post subject: Reply with quote

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
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Thu Apr 16, 2009 3:51 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help All times are GMT - 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Forum hosting provided by Reverse.net

Powered by phpBB © 2001, 2005 phpBB Group
subGreen style by ktauber