Are these two lines written in swift 4 the same? - ios

I got a deprecation warning on this line:
components.append("-b \"\(string.substring(to: string.index(before: string.endIndex)))\"")
So I changed it to:
components.append("-b \"\(String(string[..<string.endIndex]) )\"")
Is the second line okay?, because my code otherwise seems to be working fine.

Let's see
let string = "12345"
var components = [String]()
var components2 = [String]()
components.append("-b \"\(string.substring(to: string.index(before: string.endIndex)))\"")
components2.append("-b \"\(String(string[..<string.endIndex]) )\"")
print(components)
print(components2)
print(components == components2)
gives us
["-b \"1234\""]
["-b \"12345\""]
false
so the answer is, no they are not...
If your intention is to remove the last character, then you can just use dropLast:
components.append("-b \"\(string.dropLast())\"")
note that you can pass a param for the number of elements you want to drop (dropLast(2) for example)
Finally, the equivalent expression after using the partial range would be:
string[..<string.index(before: string.endIndex)]
and that is because the first expression translates to:
The index up to but not including the index before the endIndex
while the second one translates to:
The index up to but not including the endIndex
where endIndex refers to the "past the end" position

Related

(LUA) is there any way for me to cut a message and save it inside variables?

i can use string.gsub(message, " ")
but it only cuts the words.
i searched on http://lua-users.org/wiki/StringLibraryTutorial but i cant find any solution for this there
how can i save these words into variables?
for example i have message = "fun 1 true enjoy"
and i want variables to have
var level = 1
var good = true
var message = "enjoy"
Use string.match to extract the fields and then convert them to suitable types:
message = "fun 1 true enjoy"
level,good,message = message:match("%S+%s+(%S+)%s+(%S+)%s+(%S+)")
level = tonumber(level)
good = good=="true"
print(level,good,message)
print(type(level),type(good),type(message))
The pattern in match skips the first field and captures the following three fields; fields are separated by whitespace.

Selecting values with regex between two characters

I need help with regex, I have added some working Playground code on what I am trying to do, to help.
If key="id" it should return: 862
If key="pos" is should return: -301.5, 61.7, 364.6
My RegEx is var expression = key+"=(.*?)[^,]+" which is kinda close, but not exactly what I am wanting.
Any help is appreciated!
import UIKit
var data = "0. id=862, pos=(-301.5, 61.7, 364.6), rot=(-7.0, -2735.2, 0.0), remote=True, health=125"
var key = "id"
var expression = key+"=(.*?)[^,]+"
var match = data.range(of: expression, options: .regularExpression);
var value = data.substring(with: match!)
print(value)
You may match the strings using
var expression = "(?<=" + key+"=)(?:\\([^()]+\\)|[^,\\s]+)"
See the regex demo, it matches
(?<=pos=) - a key followed with = must immediately precede the current position
(?:\([^()]+\)|[^,\s]+) - match either
\([^()]+\) - a (, 1+ chars other than ( and ) and then )
| - or
[^,\s]+ - 1+ chars other than whitespace and comma.
Then, after you get the match, remove trailing ( and ):
var value = data.substring(with: match!).trimmingCharacters(in: ["(",")"])

how to remove a second AMPERSAND in a string?

1.how to remove second AMPERSAND from following string?
"apple&banana&grape&apple"
2.how to split the string at second AMPERSAND for following string? I want to ignore the first AMPERSAND and split from second AMPERSAND onwards.
"apple&banana&grape&apple"
arr = "apple&banana&grape&apple".split('&')
#arr = ["apple", "banana", "grape", "apple"]
To solve first query,
arr[0..1].join('&').concat(arr[2..-1].join('&'))
# "apple&bananagrape&apple"
For second query,
[words[0..1].join('&'), words[2..-1]].flatten
#["apple&banana", "grape", "apple"]
You can use gsub with a block:
For your first case:
index_to_remove = 2
current_index = 0
my_string = "apple&banana&grape&apple"
my_string.gsub('&') { |x| current_index += 1; current_index == index_to_remove ? '' : x}
#=> "apple&bananagrape&apple"
For your second case, you can replace the second & with a unique value and split on that:
index_to_split = 2
current_index = 0
my_string = "apple&banana&grape&apple"
my_string.gsub!('&') { |x| current_index += 1; current_index == index_to_split ? '&&' : x}
my_string.split('&&')
#=> ["apple&banana", "grape&apple"]
If you split the string by the &, it's quite simple to rejoin the first two / last two and convert back into a string or array:
words = "apple&banana&grape&apple".split('&')
# First query
words[0..1].join('&') + words[2..-1].join('&')
# Giving you: "apple&bananagrape&apple"
# Second query
[words[0..1].join('&'), words[2..-1].join('&')]
# Giving you: ["apple&banana", "grape&apple"]
You could tweak this for different length strings and separators as needed.
I imagine there's a good solution using regex matchers, but I'm not too hot on them, so hope this helps in some way!

I need to split string from a character

My string is
text1,text2
I want to split text1 and text2 by using the ','.
Try this:
s="text1,text2"
t1,t2=s:match("(.-),(.-)$")
print(t1,t2)
To get an iterator with the substrings, you can call string.gmatch.
for i in string.gmatch(example, "%P+") do
print(i)
end
To just get them into two separate strings, you can just call the iterator;
> iter = string.gmatch(indata, "%P+")
> str1 = iter()
> str2 = iter()
> print (str1)
test1
> print (str2)
test2
If you want them stored in an array instead, there's a whole discussion here how to achieve that.
#lhf added a better pattern [^,]+ in the comments, mine splits on any punctuation, his only on comma.
Try the functions given in this page:
http://lua-users.org/wiki/SplitJoin

Last Index of Character in String

How do you get the last index of a character in a string in Lua?
"/some/path/to/some/file.txt"
How do I get the index of the last / in the above string?
index = string.find(your_string, "/[^/]*$")
(Basically, find the position where the pattern "a forward slash, then zero or more things that aren't a forward slash, then the end of the string" occurs.)
This method is a bit more faster (it searches from the end of the string):
index = your_string:match'^.*()/'
Loops?!? Why would you need a loop for that? There's a 'reverse' native string function mind you, just apply it then get the first instance :) Follows a sample, to get the extension from a complete path:
function fileExtension(path)
local lastdotpos = (path:reverse()):find("%.")
return (path:sub(1 - lastdotpos))
end
You can do it in a single line of course, I split it in two for legibility's sake.
Here is a complete solution.
local function basename(path)
return path:sub(path:find("/[^/]*$") + 1)
end
local s = "/aa/bb/cc/dd/ee.txt"
local sep = "/"
local lastIndex = nil
local p = string.find(s, sep, 1)
lastIndex = p
while p do
p = string.find(s, sep, p + 1)
if p then
lastIndex = p
end
end
print(lastIndex)
You could continue find next value, until find nil,record last position

Resources