Sort an array of dictionary (swift) - arrays

let unsorted = [{Name:Amy,age:20},{Name:Bill,age:20}]
let sortedDict = sorted(unsorted){a,b in return a.Name < b.Name}
How can I sort the unsorted array according to the Name key? Above code seems doesn't work.

Your sorting syntax works (almost) if you are using a custom struct rather than a dictionary
struct Person {
let name : String
let age : Int
}
let unsortedPeople = [Person(name:"Bill", age:20), Person(name:"Amy", age:20)]
Now you can use the sorted function
let sortedDict = unsortedPeople.sorted{ $0.name < $1.name }

Your dictionary in your question is wrong, so I am assuming you have a dictionary like
let unsorted = ["Amy": Amy, "Dan": Dan, "Ben": Ben]
If so, you can sort by
let sorted = unsorted.sort { $0.0 < $1.0 }

Related

How to convert String array to Int array in Kotlin?

Kotlin has many shorthands and interesting features. So, I wonder if there is some fast and short way of converting array of string to array of integers. Similar to this code in Python:
results = [int(i) for i in results]
You can use .map { ... } with .toInt() or .toIntOrNull():
val result = strings.map { it.toInt() }
Only the result is not an array but a list. It is preferable to use lists over arrays in non-performance-critical code, see the differences.
If you need an array, add .toTypedArray() or .toIntArray().
I'd use something simple like
val strings = arrayOf("1", "2", "3")
val ints = ints.map { it.toInt() }.toTypedArray()
Alternatively, if you're into extensions:
fun Array<String>.asInts() = this.map { it.toInt() }.toTypedArray()
strings.asInts()
If you are trying to convert a List structure that implements RandomAccess (like ArrayList, or Array), you can use this version for better performance:
IntArray(strings.size) { strings[it].toInt() }
This version is compiled to a basic for loop and int[]:
int size = strings.size();
int[] result = new int[size];
int index = 0;
for(int newLength = result.length; index < newLength; ++index) {
String numberRaw = strings.get(index);
int parsedNumber = Integer.parseInt(numberRaw);
result[index] = parsedNumber;
}
If you use Array.map as other answers suggest, you get back a List, not an Array. If you want to map an array strings to another array results, you can do it directly like this:
val results = Array(strings.size) { strings[it].toInt() }
This is more efficient than first mapping to a List and then copying the elements over to an Array by calling .toTypedArray().
Consider the input like this "" (empty string)
It would be better to do the filtering first. And it is true the return value is list but not array.
If you need an array, add .toTypedArray() or .toIntArray().
fun stringToIntList(data: String): List<Int> =
data.split(",").filter { it.toIntOrNull() != null }
.map { it.toInt() }
val result = "[1, 2, 3, 4, 5]".removeSurrounding("[","]").replace(" ","").split(",").map { it.toInt() }
Found following simplest
strings.chars().toArray()

String Sorting Based on Last Character in Swift

I want to sort my string array based on last character. Here is my string array:
["c_572A267C-DAC8-487D-B1AF-719FE8E3A6AB_FF6E00_2",
"b_69E21DC6-431C-4373-B4F1-90BF7FB5462B_FFC000_1"]
Now I want to sort this array based on last value that is after last underscore(_).
Is it possible ?
Thanks
sorted can provide a custom sort condition for example (assuming that all strings are not empty)
let array = ["c_572A267C-DAC8-487D-B1AF-719FE8E3A6AB_FF6E00_2", "b_69E21DC6-431C-4373-B4F1-90BF7FB5462B_FFC000_1"]
let sortedArray = array.sorted { $0.substring(from: $0.index(before: $0.endIndex)) < $1.substring(from: $1.index(before: $1.endIndex)) }
Swift 3+ the syntax is much more convenient
let array = ["c_572A267C-DAC8-487D-B1AF-719FE8E3A6AB_FF6E00_2", "b_69E21DC6-431C-4373-B4F1-90BF7FB5462B_FFC000_1"]
let sortedArray = array.sorted { $0.suffix(1) < $1.suffix(1) }
No doubt it is. By using sorted(by:), you could do it like this:
let myArray = ["c_572A267C-DAC8-487D-B1AF-719FE8E3A6AB_FF6E00_2",
"b_69E21DC6-431C-4373-B4F1-90BF7FB5462B_FFC000_1"]
let sortedArray = myArray.sorted {
guard let str1LastChar = $0.characters.last, let str2LastChar = $1.characters.last else {
return false
}
return str1LastChar < str2LastChar
}
print(sortedArray)
Note that if myArray contains any empty string ("") the sort should be as is.
One more answer with Higher Order Function:
Reverse Each word in an Array
Then, Sort
let arr = ["c_572A267C-DAC8-487D-B1AF-719FE8E3A6AB_FF6E00_2",
"b_69E21DC6-431C-4373-B4F1-90BF7FB5462B_FFC000_1"]
One Line:
let returnValue = arr.map({String($0.reversed())}).sorted().map({String($0.reversed())})
Multi Line:
let reverseEachWordsArr = arr.map { value in
return String(value.reversed())
}
let finalCharSortArr = reverseEachWordsArr.sorted().map { word in
return String(word.reversed())
}
print(finalCharSortArr)
OUTPUT:
["b_69E21DC6-431C-4373-B4F1-90BF7FB5462B_FFC000_1",
"c_572A267C-DAC8-487D-B1AF-719FE8E3A6AB_FF6E00_2"]

Remove specific object from array in swift 3

I have a problem trying to remove a specific object from an array in Swift 3. I want to remove item from an array as in the screenshot but I don't know the solution.
If you have any solutions please share with me.
Short Answer
you can find the index of object in array then remove it with index.
var array = [1, 2, 3, 4, 5, 6, 7]
var itemToRemove = 4
if let index = array.index(of: itemToRemove) {
array.remove(at: index)
}
Long Answer
if your array elements confirm to Hashable protocol you can use
array.index(of: itemToRemove)
because Swift can find the index by checking hashValue of array elements.
but if your elements doesn't confirm to Hashable protocol or you don't want find index base on hashValue then you should tell index method how to find the item. so you use index(where: ) instead which asks you to give a predicate clouser to find right element
// just a struct which doesn't confirm to Hashable
struct Item {
let value: Int
}
// item that needs to be removed from array
let itemToRemove = Item(value: 4)
// finding index using index(where:) method
if let index = array.index(where: { $0.value == itemToRemove.value }) {
// removing item
array.remove(at: index)
}
if you are using index(where:) method in lots of places you can define a predicate function and pass it to index(where:)
// predicate function for items
func itemPredicate(item: Item) -> Bool {
return item.value == itemToRemove.value
}
if let index = array.index(where: itemPredicate) {
array.remove(at: index)
}
for more info please read Apple's developer documents:
index(where:)
index(of:)
According to your code, the improvement could be like this:
if let index = arrPickerData.index(where: { $0.tag == pickerViewTag }) {
arrPickerData.remove(at: index)
//continue do: arrPickerData.append(...)
}
The index existing means Array contains the object with that Tag.
I used the solutions provided here: Remove Specific Array Element, Equal to String - Swift Ask Question
this is one of the solutions there (in case the object was a string):
myArrayOfStrings = ["Hello","Playground","World"]
myArrayOfStrings = myArrayOfStrings.filter{$0 != "Hello"}
print(myArrayOfStrings) // "[Playground, World]"

Check each value inside a nested array of a dictionary Swift

I know this question might seem obvious to some, but i can't get around a proper solution.
I have a dictionary
someDict = [String : [Int]]
Also i have an Integer variable and a string
var someNumber = Int()
var someString = String()
My goal is to compare if someString = someDict key and if yes - compare every Int value inside it's nested array to someNumber (check whether it's smaller or bigger and give some output).
Thank you!
First you look for the key in the dictionary that matches the one you're after — so we loop through all the keys.
Then, once we find a match, we loop through all the contents of that keys value. In this case, its our array of numbers.
let someDict = ["matchingString" : [6,7,5,4]]
var someNumber = 5
var someString = "matchingString"
for (someDictKey, numbers) in someDict {
if someDictKey == someString {
// Key Found
for number in numbers {
if number == someNumber {
// Number Found
} else {
// no matching number found
}
}
} else {
// No matching key found
}
}
Try it in a playground.
You can make use of optional chaining, without the need to explicitly loop over the dictionary entries.
var someDict = [String : [Int]]()
someDict["SomeString"] = [Int](1...5)
let someString = "SomeString"
let someNumber = 2
if someDict[someString]?.contains(someNumber) ?? false {
print("Dict value array for key '\(someString)' contains value \(someNumber).")
}
else {
print("Dict value array for key '\(someString)' does not contain value \(someNumber).")
}
/* Prints: Dict value array for key 'SomeString' contains value 2. */
If we're dealing with a huge dictionary, looping over all dictionary entries kind of defeats the purpose of dictionaries O(1) hash value lookup (i.e., just attempting to access the key directly).
Try this:
var someDict = [String : [Int]]()
someDict["a"] = [1, 2, 3]
someDict["b"] = [4, 5, 6]
var str = "a"
var number = 3
for (key, value) in someDict {
if key == str {
for num in value {
if num == number {
print("matched")
} else {
print("Oops")
}
}
} else {
print("nope")
}
}
You can simply ask the dictionary for the key you're interested into, and enumerate within the corresponding object:
// this helps us get rid of having to unwrap someDict["someString"] first
for intVal in someDict["someString"] ?? [Int]() {
print(intVal < someNumber ? "smaller" : "not smaller")
}
Or, if your interested on finding the numbers smaller that someNumber, you can use the filtering support:
let smallerNumbers = (someDict[someString] ?? [Int]()).filter({$0 < someNumber})

Swift 2 - Check if an array contains a value from another smaller array

I am trying to compare two arrays (array1, array2) and if a specific key value is contained in array2, the key value in array1 that contains the array2 value needs to be printed out with its 'indexPath'.
The code I have almost works however, the app crashes because while going trough the keys, array2 goes out of range because it contains less indexes that the array1
How can I make the code look for matches if other array is smaller?
let array1 = [["aaa","bbb","ccc","ddd","eee"], ["fff","ggg","hhh","matched","iii"], ["lll","mmm","nnn","ooo","ppp"], ["666","777","888","999","000"] ] //4 elements
let countArray1 = array1.enumerate()
let array2 = [["111","222"], ["333","444"], ["matched","555"]] // 3 elements
for (index, element) in countArray1{
let containedValue = array1[index].contains(array2[index][0])
if (containedValue) == true{
print("The index of the contained value is: ????") //error
}
}
I would turn the smaller 2D array into a 1D array and then loop through the both dimensions of the bigger array and use NSArray.contains:
DISCLAIMER: this code is untested. #Community: if you stumble upon this and notice a mistake or something that can be better written, comment or edit. I use Obj-C more than Swift.
//convert 2D array to 1D
func from2Dto1D(array: NSArray) -> NSArray {
var newArr = NSMutableArray()
for (d1) in array {
for (d2) in d1 {
newArr.append(d2)
}
}
return newArr as NSArray
}
func hasMatch(array1: NSArray, array2: NSArray) -> boolean {
var bigger: NSArray
var smaller: NSArray
if (array1.count > array2.count){
bigger = array1
smaller = from2Dto1D(array2)
}else{
bigger = array2
smaller = from2Dto1D(array1)
}
for (d1) in bigger{
for (item) in d1 {
if (smaller.contains(item)){
print("Match found");
return true
}
}
}
return false
}
You could flatten out both the arrays and then enumerate them to check which index the objects match at.
let array1 = [["aaa","bbb","ccc","ddd","eee"], ["fff","ggg","hhh","matched","iii"], ["lll","mmm","nnn","ooo","ppp"], ["666","777","888","999","000"] ] //4 elements
let array2 = [["111","222"], ["333","444"], ["matched","555"]] // 3 elements
let flat1 = Array(array1.flatten())
let flat2 = Array(array2.flatten())
for (index1,object1) in flat1.enumerate() {
for (index2,object2) in flat2.enumerate() {
if object2 == object1 {
print("index1 is: \(index1). Index 2 is \(index2)")
}
}
}

Resources