Swift 3 - Array mapping. Add placeholder values in array based on relationship - ios

My first array is:
arr1 = [1, 2, 3, 4, 5]
My second array is:
arr2 = [2, 3, 4]
My third array is:
arr3 = ["2a", "3a", "4a"]
arr2 and arr3 are related by index values, i.e., arr2[0] relates to arr3[0], same for [1] and [2].
I have been able to compare arr2 against arr1 and add placeholder values so my placeholder array for them is
arr1to2 = ["No match", 2, 3, 4, "No Match"]
Now I need to compare arr3 against arr2 to arr1 (alternatively arr1to2), so my output should be
array_final = ["No match", 2a, 3a, 4a, "No match"]
I need to have the relationship maintained between index values of array_final and arr1to2 as well. [1] relates [1], [2] to [2], [3] to [3].

You can do it this way:
let arr1 = [1, 2, 3, 4, 5]
let arr2 = [2, 3, 4]
let arr3 = ["2a", "3a", "4a"]
// first lets join arr2 and arr3 to a dictionary
var dict: [Int: String] = [:]
zip(arr2, arr3).forEach({ (pair) in
dict[pair.0] = pair.1
})
// and then just map each value in arr1 according to the dictionary, or provide a "No match" default
let result = arr1.map { (value) -> String in
return dict[value] ?? "No match"
}
print(result)

Related

Improving on the efficiency of my filtering of arrays with potentially hundreds of thousands of elements

I have an array of numbers. I want to find those in array1 that aren't also in array2, like this:
var array1 = [1, 2, 3, 4]
var array2 = [2, 4, 5, 6]
var result = [1, 3]
I've solved the problem by looping through all the numbers in the array2 and adding them to a dictionary. Then I loop through array1 and add those that aren't in the dictionary to the result array:
var result: [Int] = []
var numbersDict: [Int : Bool] = [:]
for element in array2 {
numbersDict[element] = true
}
for element in array1 {
if numbersDict[element] == nil {
result.append(element)
}
}
I also want to find those in array2 that aren't in array1
var array1 = [1, 2, 3, 4]
var array2 = [2, 4, 5, 6]
var result = [5, 6]
I've solved this like this:
var result: [Int] = []
var numbersDict: [Int : Bool] = [:]
for element in array1 {
numbersDict[element] = true
}
for element in array2 {
if numbersDict[element] == nil {
result.append(element)
}
}
How can I do this in the most efficient way? Assuming that these arrays could potentially be tens if not hundreds of thousands of numbers long. Should I be using sorting?
Just use Set.
Example which gets elements in array1 but not in array2:
let array1: Set = [1, 2, 3, 4]
let array2: Set = [2, 4, 5, 6]
let result = array1.subtracting(array2)
print(result)
// Prints: [1, 3] <- Order may vary since it is a set
Just switch the two sets around to get the opposite result, of in array2 but not in array1.
There are lots of Set operations, another one is intersection(_:):
let result = array1.intersection(array2)
print(result)
// Prints: [2, 4] <- Again, no order

Swift 3 - Compare two unequal length arrays and append placeholder values in it to make them equal

My first array is
arr1 = [1, 2, 3, 4 , 5]
My second array is
arr2 = [2, 3, 4]
I want to compare arr1 against arr2 and output a third array with the output
arr3 = ["No match", 2, 3, 4, "No match"]
So that I have added a placeholder value at indices where arr1 and arr2 dont match. Arr1 and arr2 will not always be sorted.
How do i go about this in Swift 3? Can't come up with a loop that will work :/
a simple solution will be
let arr1 = [1,2,3,4,5,6]
let arr2 = [2,3,4]
var arr3 = [String]()
for value in arr1{
if arr2.contains(value){
arr3.append("\(value)")
} else {
arr3.append("No Match")
}
}
one line solution would be
let results = arr1.map {arr2.contains($0) ? "\($0)" : "No Match"}
you can try this :
let arr1 = [1,2,7,3,4,5]
let arr2 = [2,3,4,7]
var arr3 = [Any]()
var count = Int()
let sortedArr1 = arr1.sorted()
let sortedArr2 = arr2.sorted()
let arrCount1 = sortedArr1.count
let arrCount2 = sortedArr2.count
if arrCount1 > arrCount2 {
count = arrCount1
}else {
count = arrCount2
}
for i in 0..<count {
if sortedArr2.contains(sortedArr1[i]){
arr3.append(sortedArr1[i])
}else {
arr3.append("Not Matched")
}
}
When you print the output array it will give you the desired result:
print(arr3) //Outputs :["Not Matched", 2, 3, 4, "Not Matched", 7]
Or the one line code will be like as follows:
let arr3 = sortedArr1.map {sortedArr2.contains($0) ? "\($0)" : "Not Matched"}
print(arr3) //Outputs :["Not Matched", 2, 3, 4, "Not Matched", 7]
if you want array of string instead of any. you can try this
let arr1 = [1, 2, 3, 4 , 5]
let arr2 = [2, 3, 4]
let test = arr1.map{
(item) -> String in
if arr2.contains(item){
return "\(item)"
}else{
return "No match"
}
}
print(test)//["No match", "2", "3", "4", "No match"]

IOS - How to catch dynamic array dimension from JSON in Swift 3

Hello everyone I need help. I have JSON with dynamic array dimension value. This is the example :
//array 1 dimension
"array_dimension" : 1, //we can change to 2 dimension or more
"my_array" : [0, 1, 2, 3, 4] //the value adjust with array_dimension
//array 2 dimension
"array_dimension" : 2,
"my_array" : [[0, 1, 2], [3, 4], [5]]
//array 3 dimension
"array_dimension" : 3,
"my_array" : [[[0, 1], [2]], [[3], [4]], [[5]]]
And now I only can catch the my_array value in variable with static array dimension like this :
//example value in array 2 dimension
"array_dimension" : 2,
"my_array" : [[0, 1, 2], [3, 4], [5]]
//Program to catch my_array value in Swift 3
if let my_array = myJSON["my_array"] as? [[Int]] {
var myArray: [[Int]]?
myArray = my_array
} else {
print("\(TAG) error : JSON parsing my_array not found")
}
How can I catch all dynamic array dimension from my_array value in a variable (Swift 3) ?
UPDATE :
How I can use that technique ?
Your array is not Array<Int>, your array is Array<Any>.
Inside application you know how deep arrays in your root array. Based on that, you can take "last" meta array, that contains Int values (with type Array<Any>). After that you can get element by index and use:
let value : Int = Null;
if let intElement = array[index] as? Int {
value = intElement;
}
else
{
print("Error with element type (print element)");
}

Two arrays in key and value in Dictionary swift

I have two Int arrays, for example:
array1 = [1, 2, 3, 4] as Int
array2 = [10, 20, 30, 40] as Int
for work I need create Dictionary where Key - it's element from array1 and Value - it's element from array2, in my example - [1:10, 2:20, 3:30, 4:40] as [Int:Int].
So, when I create loop:
for i in 0..<arrayOfKeys.count {
dictionaryOfData[arrayOfKeys[i]] = arrayOfValues[i]
}
i see only last [4:40], but I know that I must have the Dictionary with 4 keys-values.
Give me, please, advise, how to do it in swift?!
upd, i find my problem - keys MUST be unique! So, thanks a lot for your answer and i knew about zip in swift
Try this:
let array1 = [1, 2, 3, 4]
let array2 = [10, 20, 30, 40]
var dict = [Int: Int]()
zip(array1, array2).forEach { dict[$0] = $1 }
print(dict)
Few solutions off the top of my head:
Init Arrays + Dict
let arrayOfValues = [1,2,3,4]
let arrayOfKeys = [1,2,3,4]
var arrayOfDict = [Int:Int]()
For loop solution:
for i in 0..<arrayOfKeys.count {
if i < arrayOfValues.count {
let key = arrayOfKeys[i]
let value = arrayOfValues[i]
arrayOfDict[key] = value
}
}
Using zip method solution:
for (key, value) in zip(arrayOfValues, arrayOfKeys) {
arrayOfDict[key] = value
}
From apple docs:
zip: A sequence of pairs built out of two underlying sequences, where
the elements of the ith pair are the ith elements of each underlying
sequence.(iOS (9.0 and later))
If you can't use Zip you can enumerate your array if both arrays have the same number of elements:
let array1 = [1, 2, 3, 4]
let array2 = [10, 20, 30, 40]
var result: [Int:Int] = [:]
array1.enumerate().forEach{ result[$0.element] = array2[$0.index] }
result // [2: 20, 3: 30, 1: 10, 4: 40]
Here is an updated answer for Swift 4 taken from www.tutorialspoint.com:
let cities = ["Delhi", "Bangalore", "Hyderabad"]
let distances = [2000, 10, 620]
let cityDistanceDict = Dictionary(uniqueKeysWithValues: zip(cities, distances))

How to remove single object in array from multiple matching object

var testarray = NSArray()
testarray = [1,2,2,3,4,5,3]
print(testarray)
testarray.removeObject(2)
I want to remove single object from multiple matching object like
myArray = [1,2,2,3,4,3]
When I remove
myArray.removeObject(2)
then both objects are deleted. I want remove only single object.
I tried to use many extension but no one is working properly. I have already used this link.
Swift 2
Solution when using a simple Swift array:
var myArray = [1, 2, 2, 3, 4, 3]
if let index = myArray.indexOf(2) {
myArray.removeAtIndex(index)
}
It works because .indexOf only returns the first occurence of the found object, as an Optional (it will be nil if object not found).
It works a bit differently if you're using NSMutableArray:
let nsarr = NSMutableArray(array: [1, 2, 2, 3, 4, 3])
let index = nsarr.indexOfObject(2)
if index < Int.max {
nsarr.removeObjectAtIndex(index)
}
Here .indexOfObject will return Int.max when failing to find an object at this index, so we check for this specific error before removing the object.
Swift 3
The syntax has changed but the idea is the same.
Array:
var myArray = [1, 2, 2, 3, 4, 3]
if let index = myArray.index(of: 2) {
myArray.remove(at: index)
}
myArray // [1, 2, 3, 4, 3]
NSMutableArray:
let myArray = NSMutableArray(array: [1, 2, 2, 3, 4, 3])
let index = myArray.index(of: 2)
if index < Int.max {
myArray.removeObject(at: index)
}
myArray // [1, 2, 3, 4, 3]
In Swift 3 we call index(of:) on both Array and NSMutableArray, but they still behave differently for different collection types, like indexOf and indexOfObject did in Swift 2.
Swift 5: getting index of the first occurrence
if let i = yourArray.firstIndex(of: yourObject) {
yourArray.remove(at: i)
}
If you want to remove all duplicate objects then you can use below code.
var testarray = NSArray()
testarray = [1,2,2,3,4,5,3]
let set = NSSet(array: testarray as [AnyObject])
print(set.allObjects)

Resources