How to find selected index values with index array in swift? - ios

I having two Arrays.
Index values Array1 = [1,2,3,4]
totalarray = [100,20,40,50,76,88,90,76,55,43,32,12,345]
How do I find Array1 index values in totalarray.

Assuming you want to find the indexes where each element of Array1 appears in totalarray, you can use a map statement:
let Array1 = [1,2,3,4]
let totalarray = [100,20,40,50,76,88,90,76,55,43,32,12,345]
let indexes = Array1.map { totalarray.firstIndex(of: $0) }
print(indexes)
Note that none of the values in Array1 appear in totalArray, so the above code will put an array of 4 nulls into indexes, so the output will be [nil, nil, nil, nil]
If you used the sample data from Sanzio Angeli's answer:
let Array1 = [7, 6, 4, 8]
let totalarray = [20, 30, 6, 7, 10, 40]
The output would be:
[Optional(3), Optional(2), nil, nil]
The other way to interpret your question is that you want to treat every value in Array1 as an index into totalarray, and want to build an array of the elements at those indexes in totalarray. As mentioned in Sulthan's comment, that could would look like this:
let Array1 = [1,2,3,4]
let totalarray = [100,20,40,50,76,88,90,76,55,43,32,12,345]
let indexes = Array1.map { totalarray[$0] }
print(indexes)
And would print the output [20, 40, 50, 76]. However that code would crash if any of the values in Array1 were larger than totalarray.count - 1. It really needs range checking.

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 - Array mapping. Add placeholder values in array based on relationship

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)

How to remove one duplicate value in an array?

I have two arrays for which I am comparing [Int]
let filter = strongAgainstArray.filter{weakAgainstArray.contains($0)}
This returns an array of common values in the 2 arrays. I then want to go through and remove those values from each array, which I'm doing like so
for item in filter {
for var i = 0; i < strongAgainstArray.count; i += 1 {
if item == strongAgainstArray[i] {
strongAgainstArray.removeAtIndex(i)
print("Removing a Strong against index \(item)")
}
}
for var i = 0; i < weakAgainstArray.count; i += 1 {
if item == weakAgainstArray[i] {
weakAgainstArray.removeAtIndex(i)
print("Removing a Weak against index \(item)")
}
}
}
This works fine, but let's say one of my arrays contains two entries for 12 as an example. How do I only remove one of them? As it stands, all entries of 12 are being removed entirely.
EDIT
I'm now comparing my two arrays using
let commonValues = Array(Set(strongAgainstArray).intersect(weakAgainstArray))
and then those commonValues from each array with
cleanStrongAgainstArray = Array(Set(strongAgainstArray).subtract(Set(commonValues)).sort())
cleanWeakAgainstArray = Array(Set(weakAgainstArray).subtract(Set(commonValues)).sort())
This is a much better overall solution, but I'm still eventually running into the same issue, albeit slightly different than before.
In the playground, for example...
let array = [7,7,9]
let test = Array(Set(array))
test comes back containing [7, 9], and I need to keep that extra 7. How do I do that?
If the order of the arrays aren't important then you can easily achieve the whole solution using Sets:
let dirtyArray = [1,4,6,1,56,4,4,66,23,3,3,12]
let dirtyArray1 = [3,1,6,99,54]
let cleanArray = Array(Set(dirtyArray).union(Set(dirtyArray1)))
print (cleanArray)
[12, 54, 23, 4, 6, 66, 99, 56, 1, 3]
If order is important, use NSOrderedSet:
let strongAgainstArray = [1, 2, 3, 4]
let weakAgainstArray = [3, 4, 5, 6]
let result = NSOrderedSet(array: (strongAgainstArray + weakAgainstArray)).array

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