This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Astrophylite's profile picture

Combining Tables

Started by Astrophylite, 03 August 2015 - 06:52 PM
Astrophylite #1
Posted 03 August 2015 - 08:52 PM
Hi,

I was just about to start programming a program that would send messages and the message comes from the parameters, when I realised, how do I make it combine multiple arguments into one to then send the message off in one string?
So, my question is, how do I make it combine multiple arguments into one to then send the message off in one string?

Thanks in advanced,
_Zircon_
TheOddByte #2
Posted 03 August 2015 - 09:09 PM
From what I understood you want to do something like this?

--# Just an example table
local t = {
    "hello", "world", "foo", "bar"
}
local text = "" --# This would be the string you'd send
for i = 1, #t do --# Loop through all the other strings
    text = text .. t[i] --# Concatenate the strings
end

print( text ) --# Outputs: helloworldfoobar

Do you have any code? If so, then please post it, as it would be helpful for a better understanding of what you mean.
Astrophylite #3
Posted 03 August 2015 - 09:20 PM
From what I understood you want to do something like this?

--# Just an example table
local t = {
	"hello", "world", "foo", "bar"
}
local text = "" --# This would be the string you'd send
for i = 1, #t do --# Loop through all the other strings
	text = text .. t[i] --# Concatenate the strings
end

print( text ) --# Outputs: helloworldfoobar

Do you have any code? If so, then please post it, as it would be helpful for a better understanding of what you mean.
I don't have any code, but there is no need to post it because you answered my question!
Thank you !

_Zircon_
TheOddByte #4
Posted 03 August 2015 - 09:24 PM
-snip-
I'm glad that I could help you, if you have any further questions then feel free to ask, if I'm not the one answering, someone else will surely answer pretty quickly.
Astrophylite #5
Posted 03 August 2015 - 09:26 PM
-snip-

I will! Thanks for your help!

_Zircon_
Astrophylite #6
Posted 03 August 2015 - 09:33 PM
Hmm. I have come across a problem.
I have used your code, but it keeps erroring with "chatbox:18: attempt to concatenate nil and string"
The Code:

local tArgs = {...}
local function printUsage()
  printError("Usages:")
  printError("chatbox say <msg>")
  printError("chatbox tell <to-player> <msg>")
  return
end
if #tArgs < 1 then
  printUsage()
  return
end
local sCommand = tArgs[1]
if sCommand == "say" then
  for i = 3, #tArgs do --starting from 3 because the msg starts from the 3rd value.
    text = text.." "..tArgs[i]
  end
  print( text )
elseif sCommand == "tell" then
  printError("Not yet implemented!")
  return
else
  printError("Unrecognized command")
  printUsage()
  return
end

Please help me with this!

_Zircon_
KingofGamesYami #7
Posted 03 August 2015 - 09:46 PM
I'd say you're running the program with less than 3 arguments. What exactly are you giving it for arguments?
TheOddByte #8
Posted 03 August 2015 - 09:46 PM
My guess would be that it's this part that errors

for i = 3, #tArgs do --starting from 3 because the msg starts from the 3rd value.
	text = text.." "..tArgs[i]
end
wouldn't that part be this instead

for i = 2, #tArgs do
	text = text .. " " .. tArgs[i]
end
because the usage is "say <message>" and not "say <parameter> <message>"

edit: ninja'd :ph34r:/>
Edited on 03 August 2015 - 07:47 PM
Astrophylite #9
Posted 03 August 2015 - 09:49 PM
I'd say you're running the program with less than 3 arguments. What exactly are you giving it for arguments?
I am running "chatbox say test test 1"

My guess would be that it's this part that errors

for i = 3, #tArgs do --starting from 3 because the msg starts from the 3rd value.
	text = text.." "..tArgs[i]
end

wouldn't that part be this instead

for i = 2, #tArgs do
	text = text .. " " .. tArgs[i]
end
because the usage is "say <message>" and not "say <parameter> <message>"

edit: ninja'd :ph34r:/>

I changed it to
 for i = 2, #tArgs do 
but that didn't change anything and it is still erroring with the exact same error.

_Zircon_
HPWebcamAble #10
Posted 04 August 2015 - 12:03 AM
This is line 18:

elseif sCommand == "tell" then

That line couldn't throw the error you got, are you sure this is the exact code you ran?



I think its actually this line that errors:

text = text.." "..tArgs[i]
The first time that is executed, 'text' hasn't been defined yet
Therefore it errors, as you are trying to combine 'nil' and whatever 'tArgs' is.

You just need to define 'text' as a blank string:

if sCommand == "say" then

  local text = ""
  for i = 3, #tArgs do
    text = text.." "..tArgs[i]
  end
  print( text )

elseif sCommand == "tell" then
TheOddByte #11
Posted 04 August 2015 - 01:04 AM
Yeah now that I look through your code again, I can see that HPWebcamAble has found the error, because you're trying to concatenate with a nil variable( text ), but still, the thing I said before about doing this

for i = 2, #tArgs do
should still apply, because varargs doesn't take the program name as an argument, so the message would be the second argument in your case

local tArgs = {...}
if #args < 1 then
    error( "Usage: chatbox <text>" ) --# In this case "chatbox" would be the name of your program
else
    print( args[1] ) --# But when printing the first argument in the varargs table it prints whatever "<text>" was, and not "chatbox"
end
Bomb Bloke #12
Posted 04 August 2015 - 01:52 AM
Is there any particular need to send the message as a string? That seems to me to be a whole lot of work for absolutely no gain.

Remember you can do this:

local t = {"hello", "world", "foo", "bar"}

rednet.send(id, t)

local t = rednet.receive()
for i = 1, #t do print(t[i]) end

Also, don't forget that table.concat() is a thing:

print( table.concat( tArgs, " ", 2 ) )
Astrophylite #13
Posted 04 August 2015 - 10:22 AM
Thank you all for your help!
Bomb Bloke, I am trying to create a program that will PM people with a message or broadcast a message, using Chatboxes from MoarPeripherals.
Astrophylite #14
Posted 04 August 2015 - 11:37 AM
Mmkay… I have struck another problem. I want to add a function that, if tArgs[2] (the second argument) equals "-l" then the rest of that is the label. But, after experimenting with it, I can't because the label would then include the message, if I use table.concat(). So yeah.. I'm sorta stuck…
HPWebcamAble #15
Posted 05 August 2015 - 07:42 AM
I want to add a function that, if tArgs[2] (the second argument) equals "-l" then the rest of that is the label

When you say 'label', do you mean the name of the chat box?
I didn't know you could set the name, but the mod I used to use may have updated, or you might be using a mod I don't know about.
Anywho, it shouldn't really matter, I just wanted to know.

Some preliminary sudo-code:
Spoiler(When using the 'say' command)
tArgs[1] will be "say"
tArgs[2] to tArgs[#tArgs] will the message.
However, if "-l" is an argument inbetween tArgs[2] to tArgs[#tArgs], then tArgs[2] to tArgs[ pos of "-l" - 1 ] is the message, and tArgs[ pos of "-l" + 1 ] to tArgs[ #tArgs ] is the label

So with that in mind:

tArgs = {...}

local labelPos = #tArgs+1 --# A variable to store the position of "-l" - It defaults to the length of tArgs
for i = 3, #tArgs do --# Start from 3, 1 is "say" and 2 is the message - lets assume the message has to be at least 1 word
  if tArgs[i] == "-l" then
	labelPos = i
	break
  end
end

local msg = {} --# Stores the message
local label = {} --# Stores the label, if there was one

for i = 2, labelPos-1 do --# Continue until one before "-l", or the end of tArgs if we didn't find "-l"
  msg[ i-1 ] = tArgs[i] --# Copy the message from tArgs to msg
end

msg = table.concat(tArgs , " " , 2 , labelPos-1)

label = table.concat(tArgs , " ", labelPos+1 , #tArgs)
--# Note the second one shouldn't do anything if "-l" wasn't found
When this code has finished, 'label' and 'msg' will each be a string.

This SHOULD work, though I may have made an off-by-one error somewhere - its 11:41 PM :P/>
Tested, it works as intended

Any questions feel free to ask :)/>
Edited on 06 August 2015 - 03:35 PM
Bomb Bloke #16
Posted 06 August 2015 - 07:29 AM
Instead of this sort of thing:

local msg = {} --# Stores the message

for i = 2, labelPos-1 do --# Continue until one before "-l", or the end of tArgs if we didn't find "-l"
  msg[ i-1 ] = tArgs[i] --# Copy the message from tArgs to msg
end

msg = table.concat( msg , " " )

… you could instead just do:

local msg = table.concat( tArgs, " ", 2, labelPos - 1 )
HPWebcamAble #17
Posted 06 August 2015 - 05:23 PM
you could instead just do:

local msg = table.concat( tArgs, " ", 2, labelPos - 1 )

Didn't know it could do that, though it makes a lot of sense. :D/>

Updated my previous post
Astrophylite #18
Posted 08 August 2015 - 02:44 PM
Thank you guys! I will put this in the program and test it. Sorry, I wasn't active on this thread, I was too busy with other projects ^_^/>
Astrophylite #19
Posted 08 August 2015 - 02:50 PM
Okay, I think I have been doing too much coding today and my brain has exploded. Can someone provide me with the two functions (say and tell) with the label functionality as well please? I would greatly appreciate this.

_Zircon_
HPWebcamAble #20
Posted 09 August 2015 - 02:59 AM
Can someone provide me with the two functions (say and tell) with the label functionality as well please

So did you see my example above?

If run as a program, it separates the arguments into the 'msg' and 'label' variable.
Do what you will with it.

For the 'tell' functionality, you'll need to accept another argument, the player to tell.


If you are happy with the way it works, then great, but personally make the program work like this:
(Assuming the program is called 'chatbox')

chatbox say <label> <message>
chatbox tell <player> <label> <message>

Remember that you can do this in the shell:

chatbox tell bob "Chat Box" "hi bob"
The quotes (") makes the shell pass the contents as one argument.
Eg:

print( textutils.serialize( tArgs ) ) -->
{
  "tell",
  "bob",
  "Chat Box",
  "hi bob",
}