Jump to content




Table Manipulation

help

  • You cannot reply to this topic
7 replies to this topic

#1 jag

  • Members
  • 533 posts
  • LocationStockholm, Sweden

Posted 18 November 2013 - 04:15 PM

Example:
I got a table like so:
local values = {
	[1] = "one",
	[2] = "two",
	[3] = "tree",
	[4] = "four",
}
And I want to insert a value (not with table.insert()) in a specific location.
local function add(table,index,element)
	for i = #table,index,-1 do
		table[i+1] = table[i]
	end
	table[index] = element
	return table
end

Basically push the values at the position entered, ex:
add(values,3,"two point five")
which ends up with a table like so
values = {
	[1] = "one",
	[2] = "two",
	[3] = "two point five",
	[4] = "tree",
	[5] = "four"
}

Is the example function I provided good? Or can it be done a much more elegant and compact way?
This function does not work if the table got gaps.

I need a similar function to do the same but reverse, remove a index and pull the elements after towards it, so to speak.

Ex:
local function remove(table,index)
	local max = #table
	for i = index+1,max do
		table[i-1] = table[i]
	end
	table[max] = nil
	return table
end

Which ends up with a table that looks like
remove(values,3)
values = {
	[1] = "one",
	[2] = "two",
	[5] = "four"
}

Also while testing these functions I noticed that they don't only change the internal values from the arguments but also the initial table, the same way the table.sort() does. Why is that and how do I fix that?

Edited by akaJag, 18 November 2013 - 04:16 PM.


#2 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 18 November 2013 - 06:00 PM

View PostakaJag, on 18 November 2013 - 04:15 PM, said:

This function does not work if the table got gaps.
"#tableName" returns the highest index in the table before encountering a nil value. "table.getn(tableName)" always returns the highest index in the table.

I don't see a point to the use of the "max" variable in your second function, but it otherwise looks fine to me. Except that there's no need to return the table, because:

View PostakaJag, on 18 November 2013 - 04:15 PM, said:

Also while testing these functions I noticed that they don't only change the internal values from the arguments but also the initial table, the same way the table.sort() does. Why is that and how do I fix that?
When you set a variable up as a table, it doesn't actually become the table... it becomes a pointer to the table. If you set another variable to be the same as the first, then you've got two pointers... which lead to the same table.

The only real "fix" is to manually create a new table, and copy all the indexes from the first to the second, one at a time. You've then got two different tables that you can manipulate independantly of each other.

But unless you specifically want to keep a copy of the old table, you may as well just roll with it.

Edited by Bomb Bloke, 18 November 2013 - 06:01 PM.


#3 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 18 November 2013 - 07:00 PM

A problem that you do have is you're naming the table variable table, this is a naming conflict with the table API.

View PostBomb Bloke, on 18 November 2013 - 06:00 PM, said:

"#tableName" returns the highest index in the table before encountering a nil value. "table.getn(tableName)" always returns the highest index in the table.
I think you mean table.maxn returns the highest index. table.getn is the same as #

View PostBomb Bloke, on 18 November 2013 - 06:00 PM, said:

I don't see a point to the use of the "max" variable in your second function, but it otherwise looks fine to me. Except that there's no need to return the table, because:
Removes the need to run #table again.

Edited by theoriginalbit, 18 November 2013 - 07:00 PM.


#4 jag

  • Members
  • 533 posts
  • LocationStockholm, Sweden

Posted 19 November 2013 - 03:13 AM

View PostBomb Bloke, on 18 November 2013 - 06:00 PM, said:

--snip--

View Posttheoriginalbit, on 18 November 2013 - 07:00 PM, said:

--snip--

Conclusions:
  • functions looks good, not much can get improved
  • use table.maxn instead of # or table.getn
  • dont need to return table, just edit via table pointer
New functions:
local function add(tbl,index,element)
	for i = table.maxn(tbl),index,-1 do
		tbl[i+1] = tbl[i]
	end
	tbl[index] = element
end

local function remove(tbl,index)
	local max = table.maxn(tbl)
	for i = index+1,max do
		tbl[i-1] = tbl[i]
	end
	tbl[max] = nil
end

Looks good?

Edited by akaJag, 19 November 2013 - 03:19 AM.


#5 jag

  • Members
  • 533 posts
  • LocationStockholm, Sweden

Posted 19 November 2013 - 03:22 AM

Testing the code:

addtest
Spoiler

removetest
Spoiler

results
Posted Image


Thank you both very much, 1+ on the reputation counter for ya :)

Edited by akaJag, 19 November 2013 - 03:32 AM.


#6 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 19 November 2013 - 07:28 AM

View Posttheoriginalbit, on 18 November 2013 - 07:00 PM, said:

I think you mean table.maxn returns the highest index. table.getn is the same as #
Ah. Really? I always thought it was a bit ambiguous as to what "getn" was supposed to mean. "maxn" is clearly more suited to the purpose, even if getn is NOT the same as # within the versions of ComputerCraft I've used (the highest I've gone thus far being 1.53).

I see it behaves as you're thinking on repl.it, though if I run that same script in CC I get a different output:

2,6

1,3


#7 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 19 November 2013 - 07:36 AM

View PostBomb Bloke, on 19 November 2013 - 07:28 AM, said:

-snip-
Here you go.

#8 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 19 November 2013 - 08:02 AM

Yep, CC matches that behaviour. :)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users