[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]

## Seeking More Optimal Solution - Replace single character at position in string Started by roaminggamer Jul 25 2018 04:02 PM

4 replies to this topic
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

### roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
• Corona Geek

• 7,591 posts
• Corona SDK

Hi folks.

In my game I need to replace a single letter in a string with another letter.

I have code to do this, but I'd like something a little more elegant and hopefully faster.

(Motivation: When I do this operation, I may do it hundreds of times in a row.)
```local function replaceAt( str, at, with )
if( at < 1 or at > string.len( str ) ) then
return str
elseif( at == 1 ) then
return with .. strSub( str, at+1, string.len(str) )
elseif( at == string.len( str ) ) then
return strSub( str, 1, at-1 ) .. with
end
return strSub( str, 1, at-1 ) .. with .. strSub( str, at+1, string.len(str) )
end
```
If you're a Lua wizard and have a better solution, please share.

Edited by roaminggamer, 25 July 2018 - 05:25 PM.

[TOPIC: post.html]
#2

### StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
• Contributor

• 817 posts
• Corona SDK

Assuming strSub() is just a cached string.sub(), you can dispense with the second and third checks altogether, since string.sub(s, 1, 0) and string.sub(s, #s + 1, #s) will both give you "".

For that matter, the negative indices are perfectly legitimate so you might consider making your original check something like

```if math.abs(at) > #str then
```

[TOPIC: post.html]
#3

[GLOBAL: userInfoPane.html]
• Contributor

• 235 posts
• Corona SDK

What are you using the strings for? If you do this constantly, hundreds of times in a row the bigger hidden cost might be all the created garbage you constantly create as each changed string is a new immutable sequence/object Lua has to hash and add into it's pool of interned strings.

[TOPIC: post.html]
#4

### ldurniat

[GLOBAL: userInfoPane.html]
ldurniat
• Contributor

• 389 posts
• Corona SDK

Hi roaminggamer,

1. Consider change data representations. Use table of characters instead of string.

2. Try
```local pattern = { }

for i=1, 100 do

pattern[#pattern + 1] = '^(.-'.. string.rep( '.', i - 1 ) .. ')(.)'

end

local function replaceAt( str, at, with )

--return at < 1 and str or str:gsub( '^(.-' .. string.rep( '.', at - 1 ) .. ')(.)', '%1' .. with )
-- OR
return at < 1 and str or str:gsub( pattern[at], '%1' .. with )

end```

I'm not sure how fast it is. You need check that yourself.

Have a nice day:)

ldurniat

Edited by ldurniat, 26 July 2018 - 10:24 AM.

[TOPIC: post.html]
#5

### carloscosta

[GLOBAL: userInfoPane.html]
carloscosta
• Contributor

• 654 posts
• Corona SDK

the smallest i could get was:

```local function replaceAt( str, at, with )
return string.sub(str, 1, at-1  )..with..(string.sub(str, at+1, string.len(str)))
end
```

this is only useful if you control the "at" variable and is not a user that can break your code.

if you can't control the "at" variable:

```local function replaceAt( str, at, with )
local length=string.len(str) -- don't know if #str is faster, but i guess not.
if( at < 1 or at > length) then
return str
else
return string.sub(str, 1, at-1  )..with..(string.sub(str, at+1, length))
end
end
```

to use:

```local stringExample="Hello World!"

local newString=replaceAt(stringValue, 2, "X")
print (newString)
```

*edit*

the fastest version with protection i can build is:

```function replaceAt(str, at, with)
return ((at < 1) or (at > string.len(str))) and str or string.sub(str, 1, at-1  )..with..string.sub(str, at+1)
end
```

regards,

Carlos.

Edited by carloscosta, 03 August 2018 - 08:06 AM.

[topic_controls]

[/topic_controls]