How do I compare two array Objects - Swift 4 - ios

I have 2 Array of type [Any] - objects of dictionaries
And other array contains other set of objects [Any] (2nd array objects are contains in first array)
I need to find the index of the first array of second array elements
eg: -
let firstArray = [["key1":6],["key2":8],["key3":64],["key4":68],["key5":26],["key6":76]]
let secondArray = [["key3":64],["key6":68]]
How can I find the firstArray index of secondArray elements

let index = firstArray.index{$0 == secondArray[0]};
print("this value ", index);
will print optional(2) , it is basically 2

First, you take the keys from your secondArray. Then, you try to find the index of key in your firstArray. Be aware that some values might be nil if the key doesn't exist.
let firstArray = [["key1":6],["key2":8],["key3":64],["key4":68],["key5":26],["key6":76]]
let secondArray = [["key3":64],["key6":68], ["key8": 100]]
let indexes = secondArray
.map({ $0.first?.key }) //map the values to the keys
.map({ secondKey -> Int? in
return firstArray.index(where:
{ $0.first?.key == secondKey } //compare the key from your secondArray to the ones in firstArray
)
})
print(indexes) //[Optional(2), Optional(5), nil]
I also added an example case where the result is nil.

Related

Filter dictionary of array objects

I am trying to filter my dictionary according to user input in UISearchController. I have following model and array of objects.
struct People {
var name: String
var id: Int
}
let first = People(name: "Atalay", id: 1)
let second = People(name: "Ahmet", id: 2)
let third = People(name: "Mehmet", id: 3)
let fourth = People(name: "Yusuf", id: 4)
let peoples: [People] = [first, second, third, fourth, fifth]
I put them into a dictionary to create section indexed table view with following code.
var dict: [String: [People]] = Dictionary(grouping: peoples, by: { (people) -> String in
return String(people.name.prefix(1))
})
Above code gives me a dictionary with first letter of People names. Now, I would like to filter my array according to user input. However, I tried following code for filtering but it is not working as I expected.
let filteredDict = (dict.filter { $0.1.contains { $0.name.lowercased().contains("ata") } })
It returns all "A" letter section indexes like ["A": People(name: "Atalay", id: 1), People(name: "Ahmet", id: 2)]
How can I achieve filter also my array inside dictionary?
If I'm not mistaken, you want your final dictionary to have all the keys and only the filtered array of items as the values. If that is right, reduce is the tool for that:
let filtered = dict.reduce(into: [String: [People]]()) {
$0[$1.key] = $1.value.filter { $0.name.lowercased().contains("ata") }
}
I decided it was simplest to get this right by using an old fashioned for loop and filter each group separately
var filtered = [String: [People]]()
for (k, v) in dict {
let result = v.filter {$0.name.lowercased().contains("ata")}
if result.count > 0 {
filtered[k] = result
}
}
Note that if you want to keep all the groups in the result dictionary just skip the if result.count > 0 condition
How can I achieve filter also my array inside dictionary?
You should have an array first, you can use flatMap to group all the values in your filteredDict
let array = filteredDict.flatMap { $0.value }
Then you just filter the array as usually
let filteredArray = array.filter { $0.name.lowercased().contains("ata") }

Sorting array of dictionaries by value after for loop?

I've seen a lot of answers to similar questions but none of the methods have worked so far.
if let users = snapshot.value!["users"] as? Dictionary<String,AnyObject> {
each.users = Int(users.count)
var pointsArray = [Dictionary<String,Int>]()
for (key, value) in users {
let uid = key
let points = value["points"] as! Int
pointsArray.append([uid : points])
}
I'm then needing to sort pointsArray by the "points", sort it from high to low, grab the 0th (highest) element, then grab the uid to use.
I've tried:
var myArr = Array(pointsArray.keys)
var sortedKeys = sort(myArr) {
var obj1 = dict[$0] // get ob associated w/ key 1
var obj2 = dict[$1] // get ob associated w/ key 2
return obj1 > obj2
}
This gives me
Value of type [ Dictionary <String,Int>] has no member keys.
I guess that's cause I'm trying to run the sort on my array of dicts vs the dicts themselves? How do I switch this up to get into the actual dictionaries vs. running the sort on the array?
Right - you're not properly accessing the keys of the dictionaries.
Here's a working code:
var pointsArray = [Dictionary<String, Int>]()
pointsArray.append(["1" : 10])
pointsArray.append(["2" : 45])
pointsArray.append(["3" : 30])
// sort by points
let sorted = pointsArray.sort({ $0.first!.1 > $1.first!.1 })
print(sorted) // [["2": 45], ["3": 30], ["1": 10]]
Array(pointsArray.keys) - this doesn't work, because pointsArray is an array, therefore it doesn't have keys property. The contents of pointsArray are dictionaries and they have keys. So you can access the keys of the first dictionary like this: pointsArray[0].keys

Finding the index of 'NSURL item' in 'NSURL array'

I have 2 arrays of [NSURL] and they have the same elements with different order. I am trying to use the array1's indexpath to get the member, and detect member's indexPath in the other array.
I couldn't figure out if I can detect the member's index on type NSURL. I thought one way could be using for loop for the second array, however the way I could think of was..
For loop through the array2 and convert each to string to have a [string] and using another for loop to find the index of the string that I'm looking for
let array1 = [NSURL]()
let array2 = [NSURL]()
array1 = [abc, qwe, jkl]
array2 = [jkl, abc, qwe]
// To wrap up..
// For jkl, I want to use array1[2] and get array2[?]
let searchIndex = 2
if array1[2].absoluteString.isNotEmpty {
let stringToSearch = array1[2].absoluteString
}
let index = array2.indexOf { $0.absoluteString == array1[2].absoluteString }

How to append associative array elements in Swift

How do I create and append to an associative array in Swift? I would think it should be something like the following (note that some values are strings and others are numbers):
var myArray = []
var make = "chevy"
var year = 2008
var color = "red"
myArray.append("trackMake":make,"trackYear":year,"trackColor":color)
The goal is to be able to have an array full of results where I can make a call such as:
println(myArray[0]["trackMake"]) //and get chevy
println(myArray[0]["trackColor"]) //and get red
Simply like this:
myArray.append(["trackMake":make,"trackYear":year,"trackColor":color])
Add the brackets. This will make it a hash and append that to the array.
In such cases make (extensive) use of let:
let dict = ["trackMake":make,"trackYear":year,"trackColor":color]
myArray.append(dict)
The above assumes that your myArray has been declared as
var myArray = [[String:AnyObject]]()
so the compiler knows that it will take dictionary elements.
I accept above answer.It is good.Even you have given correct answer,I like to give simplest way.The following steps are useful,if you guys follow that.Also if someone new in swift and if they go through this,they can easily understand the steps.
STEP 1 : Declare and initialize the variables
var array = Array<AnyObject>()
var dict = Dictionary<String, AnyObject>()
var make = "chevy"
var year = 2008
var color = "red"
STEP 2 : Set the Dictionary(adding keys and Values)
dict["trackMake"] = make
dict["trackYear"] = year
dict["trackColor"] = color
println("the dict is-\(dict)")
STEP 3 : Append the Dictionary to Array
array.append(dict)
println("the array is-\(array)")
STEP 4 : Get Array values to variable(create the variable for getting value)
let getMakeValue = array[0]["trackMake"]
let getYearValue = array[0]["trackYear"]
let getColorValue = array[0]["trackColor"]
println("the getMakeValue is - \(getMakeValue)")
println("the getYearValue is - \(getYearValue)")
println("the getColorVlaue is - \(getColorValue)")
STEP 5: If you want to get values to string, do the following steps
var stringMakeValue:String = getMakeValue as String
var stringYearValue:String = ("\(getYearValue as Int)")
var stringColorValue:String = getColorValue as String
println("the stringMakeValue is - \(stringMakeValue)")
println("the stringYearValue is - \(stringYearValue)")
println("the stringColorValue is - \(stringColorValue)")
STEP 6 : Finally the total output values are
the dict is-[trackMake: chevy, trackColor: red, trackYear: 2008]
the array is-[{
trackColor = red;
trackMake = chevy;
trackYear = 2008;
}]
the getMakeValue is - Optional(chevy)
the getYearValue is - Optional(2008)
the getColorVlaue is - Optional(red)
the stringMakeValue is - chevy
the stringYearValue is - 2008
the stringColorValue is - red
Thank You
This sounds like you are wanting an array of objects that represent vehicles. You can either have an array of dictionaries or an array of vehicle objects.
Likely you will want to go with an object as Swift arrays and dictionaries must be typed. So your dictionary with string keys to values of differing types would end up having the type [String : Any] and you would be stuck casting back and forth. This would make your array of type [[String : Any ]].
Using an object you would just have an array of that type. Say your vehicle object's type is named Vehicle, that would make your array of type [Vehicle] and each array access would return an instance of that type.
If I want to try it with my own statement. Which also I want to extend my array with the data in my dictionary and print just the key from dictionary:
var myArray = ["Abdurrahman","Yomna"]
var myDic: [String: Any] = [
"ahmed": 23,
"amal": 33,
"fahdad": 88]
for index in 1...3 {
let dict: [String: Any] = [
"key": "new value"
]
// get existing items, or create new array if doesn't exist
var existingItems = myDic[myArray] as? [[String: Any]] ?? [[String: Any]]()
// append the item
existingItems.append(myArray)
// replace back into `data`
myDic[myArray] = existingItems
}

How do I get the key at a specific index from a Dictionary in Swift?

I have a Dictionary in Swift and I would like to get a key at a specific index.
var myDict : Dictionary<String,MyClass> = Dictionary<String,MyClass>()
I know that I can iterate over the keys and log them
for key in myDict.keys{
NSLog("key = \(key)")
}
However, strangely enough, something like this is not possible
var key : String = myDict.keys[0]
Why ?
That's because keys returns LazyMapCollection<[Key : Value], Key>, which can't be subscripted with an Int. One way to handle this is to advance the dictionary's startIndex by the integer that you wanted to subscript by, for example:
let intIndex = 1 // where intIndex < myDictionary.count
let index = myDictionary.index(myDictionary.startIndex, offsetBy: intIndex)
myDictionary.keys[index]
Another possible solution would be to initialize an array with keys as input, then you can use integer subscripts on the result:
let firstKey = Array(myDictionary.keys)[0] // or .first
Remember, dictionaries are inherently unordered, so don't expect the key at a given index to always be the same.
Swift 3 : Array() can be useful to do this .
Get Key :
let index = 5 // Int Value
Array(myDict)[index].key
Get Value :
Array(myDict)[index].value
Here is a small extension for accessing keys and values in dictionary by index:
extension Dictionary {
subscript(i: Int) -> (key: Key, value: Value) {
return self[index(startIndex, offsetBy: i)]
}
}
You can iterate over a dictionary and grab an index with for-in and enumerate (like others have said, there is no guarantee it will come out ordered like below)
let dict = ["c": 123, "d": 045, "a": 456]
for (index, entry) in enumerate(dict) {
println(index) // 0 1 2
println(entry) // (d, 45) (c, 123) (a, 456)
}
If you want to sort first..
var sortedKeysArray = sorted(dict) { $0.0 < $1.0 }
println(sortedKeysArray) // [(a, 456), (c, 123), (d, 45)]
var sortedValuesArray = sorted(dict) { $0.1 < $1.1 }
println(sortedValuesArray) // [(d, 45), (c, 123), (a, 456)]
then iterate.
for (index, entry) in enumerate(sortedKeysArray) {
println(index) // 0 1 2
println(entry.0) // a c d
println(entry.1) // 456 123 45
}
If you want to create an ordered dictionary, you should look into Generics.
From https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/CollectionTypes.html:
If you need to use a dictionary’s keys or values with an API that takes an Array instance, initialize a new array with the keys or values property:
let airportCodes = [String](airports.keys) // airportCodes is ["TYO", "LHR"]
let airportNames = [String](airports.values) // airportNames is ["Tokyo", "London Heathrow"]
SWIFT 3. Example for the first element
let wordByLanguage = ["English": 5, "Spanish": 4, "Polish": 3, "Arabic": 2]
if let firstLang = wordByLanguage.first?.key {
print(firstLang) // English
}
In Swift 3 try to use this code to get Key-Value Pair (tuple) at given index:
extension Dictionary {
subscript(i:Int) -> (key:Key,value:Value) {
get {
return self[index(startIndex, offsetBy: i)];
}
}
}
SWIFT 4
Slightly off-topic: But here is if you have an
Array of Dictionaries i.e: [ [String : String] ]
var array_has_dictionary = [ // Start of array
// Dictionary 1
[
"name" : "xxxx",
"age" : "xxxx",
"last_name":"xxx"
],
// Dictionary 2
[
"name" : "yyy",
"age" : "yyy",
"last_name":"yyy"
],
] // end of array
cell.textLabel?.text = Array(array_has_dictionary[1])[1].key
// Output: age -> yyy
Here is an example, using Swift 1.2
var person = ["name":"Sean", "gender":"male"]
person.keys.array[1] // "gender", get a dictionary key at specific index
person.values.array[1] // "male", get a dictionary value at specific index
I was looking for something like a LinkedHashMap in Java. Neither Swift nor Objective-C have one if I'm not mistaken.
My initial thought was to wrap my dictionary in an Array. [[String: UIImage]] but then I realized that grabbing the key from the dictionary was wacky with Array(dict)[index].key so I went with Tuples. Now my array looks like [(String, UIImage)] so I can retrieve it by tuple.0. No more converting it to an Array. Just my 2 cents.

Resources