Related
I need to use replacingOccurrences to get a new string, but my question is, I can't use let in if.
I don't know how to do...confused so much till now
my issue just like what I quote in title, it is system warning.and my code as below:
let newlastfive1 = lastfive
let newlastfive2 = lastfive
let newlastfive3 = lastfive
//replace aeoiu
if (lastfive.range(of: "a", options: .regularExpression) != nil)
{
let newlastfive1 = lastfive.replacingOccurrences(of: "a", with: "á")
let newlastfive2 = lastfive.replacingOccurrences(of: "a", with: "ǎ")
let newlastfive3 = lastfive.replacingOccurrences(of: "a", with: "à")
}
if (lastfive.range(of: "e", options: .regularExpression) != nil)
{
newlastfive1.replacingOccurrences(of: "e", with: "é")
newlastfive2.replacingOccurrences(of: "e", with: "ě")
newlastfive3.replacingOccurrences(of: "e", with: "è")
}
if (lastfive.range(of: "o", options: .regularExpression) != nil)
{
newlastfive1.replacingOccurrences(of: "o", with: "ó")
newlastfive2.replacingOccurrences(of: "o", with: "ǒ")
newlastfive3.replacingOccurrences(of: "o", with: "ò")
}
if (lastfive.range(of: "i", options: .regularExpression) != nil)
{
newlastfive1.replacingOccurrences(of: "i", with: "í")
newlastfive2.replacingOccurrences(of: "i", with: "ǐ")
newlastfive3.replacingOccurrences(of: "i", with: "ì")
for I need to replace only one character in "aeiou",
this mean when we have two, we need to decide which one we need to pick.
for example, this string "hallo", in this case, we need to pick "a",not "a"&"o", only one character once.
priority should follow this : a>e>o>I>u>ü
I'm going to guess that you want 3 copies of the original string, each with letter-to-letter replacements?
Take a look at this code:
let origString: String = "This is your test of looping replacement"
// characters to replace
let origChars: [String] = ["a", "e", "i", "o", "u"]
// replace with these characters
let replChars: [[String]] = [
["á", "é", "í", "ó", "ú"],
["ǎ", "ě", "ǐ", "ǒ", "ǔ"],
["à", "è", "ì", "ò", "ù"],
]
// mutable array of copies of the original string
var resultStrings: [String] = Array(repeating: origString, count: replChars.count)
// for each copy
for i in 0..<resultStrings.count {
// for each orig char
for (oChar, rChar) in zip(origChars, replChars[i]) {
// replace with replacement car
resultStrings[i] = resultStrings[i].replacingOccurrences(of: oChar, with: rChar)
}
}
// print the original string
print(origString)
// print the resulting replacement strings
resultStrings.forEach {
print($0)
}
The output in the debug console is:
This is your test of looping replacement
Thís ís yóúr tést óf lóópíng réplácémént
Thǐs ǐs yǒǔr těst ǒf lǒǒpǐng rěplǎcěměnt
Thìs ìs yòùr tèst òf lòòpìng rèplàcèmènt
If you have more "replacement sets" you can add them to the replChars array:
// replace with these characters
let replChars: [[String]] = [
["á", "é", "í", "ó", "ú"],
["ǎ", "ě", "ǐ", "ǒ", "ǔ"],
["à", "è", "ì", "ò", "ù"],
// add more sets
["1", "2", "3", "4", "5"],
["ⓐ", "ⓔ", "ⓘ", "ⓞ", "ⓤ"],
]
Now the output in the debug console is:
This is your test of looping replacement
Thís ís yóúr tést óf lóópíng réplácémént
Thǐs ǐs yǒǔr těst ǒf lǒǒpǐng rěplǎcěměnt
Thìs ìs yòùr tèst òf lòòpìng rèplàcèmènt
Th3s 3s y45r t2st 4f l44p3ng r2pl1c2m2nt
Thⓘs ⓘs yⓞⓤr tⓔst ⓞf lⓞⓞpⓘng rⓔplⓐcⓔmⓔnt
I have this CSV String
"B,C,D,A,E\n18945,12091,14058,2907,15132\n25,122,134,428,211"
which I have separated by \n and , and got below array:
I have this array:
[["B", "C", "D", "A", "E"], ["18945", "12091", "14058", "2907", "15132"], ["25", "122", "134", "428", "211"]]
where first array inside the main array is indicating the column names, which I need to sort alphabetically based on that the remaining arrays should also sorted.
Consider a table like this:
B -> 18945 -> 25
After sort, I am expecting an output like this:
[["A", "B", "C", "D", "E"], ["2907", "18945", "12091", "14058", "15132"], ["428", "25", "122", "134", "211"]]
IMO you should try to structure your data but if you really want to go through this path you just need to sort the first collection indices and map the collections using the sorted indices. Of course this assumes all collections have the same number of elements and the collection is not empty:
let table = [["B", "C", "D", "A", "E"], ["18945", "12091", "14058", "2907", "15132"], ["25", "122", "134", "428", "211"]]
let indices = table[0].indices.sorted { table[0][$0] < table[0][$1] }
let sorted = table.map { collection in
indices.map { collection[$0] }
}
If you want to be extra paranoid and make sure your code will never crash you can get the first collection using if let and use compact map checking if the collection contains each index before accessing them using subscript:
let table = [["B", "C", "D", "A", "E"], ["18945", "12091", "14058", "2907", "15132"], ["25", "122", "134", "428", "211"]]
if let columns = table.first {
let indices = columns.indices.sorted { columns[$0] < columns[$1] }
let sorted = table.map { collection in
indices.compactMap { collection.indices ~= $0 ? collection[$0] : nil }
}
print(sorted)
}
edit/update:
For a case insensitive sort:
let indices = columns.indices.sorted { columns[$0].caseInsensitiveCompare(columns[$1]) == .orderedAscending }
For a case and diacritic insensitive sort:
let indices = columns.indices.sorted { columns[$0].localizedStandardCompare(columns[$1]) == .orderedAscending }
This will print
[["A", "B", "C", "D", "E"], ["2907", "18945", "12091", "14058", "15132"], ["428", "25", "122", "134", "211"]]
I have a array of dictionaries which contains same key but different values. I want to merge these dictionaries and add all the values of same keys just like below:
var arrayofDict = [["2019":"A"],["2019":"B"],["2019":"C"],["2018":"A"],["2018":"c"],["2017":"A"],["2017":"B"],["2017":"C"],["2016":"A"],["2015":"A"],["2015":"B"]]
expected result as an Array like:
var newDict = [["2019":["A","B","C"]],["2018":["A","C"]],["2017":["A","B","C"]],["2016":["A"]],["2015":["A","B"]]]
This shows how to build a single dictionary. Your "expected result" is an array. Is this what you really expected or did you want an array?
You can iterate the dictionary items and build up the dictionary entries:
var arrayofDict = [["2019":"A"],["2019":"B"],["2019":"C"],["2018":"A"],["2018":"c"],["2017":"A"],["2017":"B"],["2017":"C"],["2016":"A"],["2015":"A"],["2015":"B"]]
var result = [String : [String]]()
for dict in arrayofDict {
for (key, value) in dict {
result[key, default: []].append(value)
}
}
print(result)
["2016": ["A"], "2018": ["A", "c"], "2015": ["A", "B"], "2019": ["A", "B", "C"], "2017": ["A", "B", "C"]]
Or, if you want an array:
let result2 = result.map { [$0.key: $0.value] }
print(result2)
[["2015": ["A", "B"]], ["2016": ["A"]], ["2019": ["A", "B", "C"]], ["2018": ["A", "c"]], ["2017": ["A", "B", "C"]]]
as #vacawama in more functional way
let result = arrayofDict.reduce(into: [String:[String]]()) { (acc, d) in
for key in d.keys {
// don't worry to force unwrap d[key], if key exist, the value is not nil
acc[key, default: []].append(d[key]!)
}
}
i have this following data structure in my Realm object
var tags = List<Tag>()
"tags": [
{
"tagId": "80069",
"tagName": "A"
},
{
"tagId": "80070",
"tagName": "B"
},
{
"tagId": "80071",
"tagName": "C"
},
{
"tagId": "80073",
"tagName": "D"
}
]
So what i want to achieve is, I map all my tag name into my new array
this is my code
let realmObject = self.realm.objects(MyDTO.self)
let array = Array(realmOutletList).map{Array($0.tags).map{$0.tagName!}.joined(separator: ",")}
it prints out this
["A,B,C", "A,C,D", "B,C,D"]
What I want to achieve is like
["A","B","C", "A","C","D", "B","C","D"]
I need that kind of array because I am going to create a Set from the array and then compare with another array
The compared array will be like
["A","B","C", "A","C","D", "B","C","D"]
because of the compared Array and the realmObject Array is different, it always shows false when i use
let subset = filterSet.isSubset(of: mySet)
Can anyone guide me please??
Thanks
Let's walk through solving the issue:
Consider that you have:
let originalArray = ["A,B,C", "A,C,D", "B,C,D"]
First, we need to separate each string in originalArray by "," character, so we could do:
let modifiedArray = originalArray.map { $0.components(separatedBy: ",") }
We map it to transform each string to a strings array (separation).
So far, the output of modifiedArray would be:
[["A", "B", "C"], ["A", "C", "D"], ["B", "C", "D"]]
which is an array of strings array.
Second, we need to spilt each -string- array in modifiedArray (having one reduced strings array instead), so we could do:
var final = [String]()
for array in modifiedArray {
for string in array {
final.append(string)
}
}
OR by using reduce
let finalArray = modifiedArray.reduce([], +)
Therefore, finalArray would be:
["A", "B", "C", "A", "C", "D", "B", "C", "D"]
which is the desired result.
Conclusion
For a fully one-lined answer (following the high-order functions approach):
let originalArray = ["A,B,C", "A,C,D", "B,C,D"]
let desiredArray = originalArray.map { $0.components(separatedBy: ",") }.reduce([], +)
print(desiredArray) // ["A", "B", "C", "A", "C", "D", "B", "C", "D"]
Well, it's quite easy:
This
let array = Array(realmOutletList).map{Array($0.tags).map{$0.tagName!}.joined(separator: ",")}
should be this
let array = Array(realmOutletList).flatMap{Array($0.tags).map{$0.tagName!}}
That's all. And you will get your ["A","B","C", "A","C","D", "B","C","D"].
I am getting an Array from server and I store it in NSMutableArray. Now the issue is that the Array is not sorted. For eg. array = ["A","B","None","C","D"]. I want to sort it and place the "None" element at last. i.e ["A","B","C","D","None"]. Tried swapping but was unable to match the condition, as the array may increase in future. Check my code below which is not working as expected.
if array.containsObject( "None" ){
print("\(array.indexOfObject("None"))")
let noneIndex = array.indexOfObject("None")
print(noneIndex)
array.removeObject(noneIndex)
print("Remove Array:-\(array)")
array.insertObject(noneIndex, atIndex: (array.lastObject?.index)!)
print("Sorted Array:-\(array)")
}
Maybe I'm misunderstanding what it is that you need to do, but you could use sorted() on your array if you just want to sort it alphabetically.
You could also use filter to remove "None" from your array, sort it, and then append "None" as the last element
For instance, if you have
let elements = ["Alpha", "Bold", "None", "charlie", "Delta", "echo", "zebra", "k"]
You could start out by filtering it:
let filteredElements = elements.filter { $0.uppercased() != "NONE"}
Sort the filtered elements:
var sortedElements = filteredElements.sorted { $0.uppercased() < $1.uppercased()}
Append "None"
sortedElements.append("None") // ["Alpha", "Bold", "charlie", "Delta", "echo", "k", "zebra", "None"]
And be done.
Here it is combined:
let lastElement = "None"
let elements = ["Alpha", "Bold", "None", "charlie", "Delta", "echo", "zebra", "k"]
var sortedElements = elements.filter({$0.uppercased() != lastElement.uppercased()}).sorted(by: {$0.uppercased() < $1.uppercased()})
sortedElements.append(lastElement)
Hope that helps you.
var array = ["A", "B", "None", "C", "D"]
if let noneIndex = array.index(of: "None") {
array.remove(at: noneIndex)
array.append("None")
}
print(array)
This should move None at the end of the array, and sort the other elements:
let ["A", "B", "None", "C", "D"]
array.sorted { $1 == "None" || $0 < $1 } // ["A", "B", "C", "D", "None"]
This simply takes benefits of the by argument that can be passed to the sort/sorted method from Array.
Edit #MartinR had a very strong point regarding the comparison predicate from this answer, which indeed doesn't offer a strong weak ordering. Sorting the array with a correct predicate would be along the lines of:
array.sorted { $0 == "None" ? false : $1 == "None" ? true : $0 < $1 }
This will work:
// starting test array
let array = ["B", "None", "C","P","None","A", "Q"]
var sorted = array.sorted { (str1, str2) -> Bool in
return str1 < str2
}
sorted.forEach { str in
if str == "None" {
if let idx = sorted.index(of: str) {
sorted.remove(at: idx)
sorted.append(str)
}
}
}
// Sorted array is now ["A", "B", "C", "P", "Q", "None", "None"]