How to find the index of an item in a multidimensional array swiftily?
You can simplify your code slightly with enumerate()
and indexOf()
.
Also the function should return an optional tuple because the element
might not be present in the "matrix". Finally, you can make it generic:
func indicesOf<T: Equatable>(x: T, array: [[T]]) -> (Int, Int)? {
for (i, row) in array.enumerate() {
if let j = row.indexOf(x) {
return (i, j)
}
}
return nil
}
You can also make it an extension for a nested Array
of Equatable
elements:
extension Array where Element : CollectionType,
Element.Generator.Element : Equatable, Element.Index == Int {
func indicesOf(x: Element.Generator.Element) -> (Int, Int)? {
for (i, row) in self.enumerate() {
if let j = row.indexOf(x) {
return (i, j)
}
}
return nil
}
}
if let (i, j) = a.indicesOf(7) {
print(i, j)
}
Swift 3:
extension Array where Element : Collection,
Element.Iterator.Element : Equatable, Element.Index == Int {
func indices(of x: Element.Iterator.Element) -> (Int, Int)? {
for (i, row) in self.enumerated() {
if let j = row.index(of: x) {
return (i, j)
}
}
return nil
}
}
Swift 5+
extension Array where Element : Collection,
Element.Iterator.Element : Equatable, Element.Index == Int {
func indicesOf(x: Element.Iterator.Element) -> (Int, Int)? {
for (i, row) in self.enumerated() {
if let j = row.firstIndex(of: x) {
return (i, j)
}
}
return nil
}
}
Search for a value in two dimensional array
Here's a function which i implemented which checks if an element is listed within the multi-dimension array and returns the total elements found:
- using .flatMap(_:) to flattened the multi-dimension arrays into one level.
using .filter(_:) to return the elements that are allowed based on the predicate.
import UIKit
var groups = [[String]]()
// we create three simple string arrays for testing
var groupA = ["England", "Ireland", "Scotland", "Wales"]
var groupB = ["Canada", "Mexico", "United States"]
var groupC = ["China", "Japan", "South Korea"]
// then add them all to the "groups" array
groups.append(groupA)
groups.append(groupB)
groups.append(groupC)
func findElementInMultiDimension(element: String) -> Int {
var count = 0
let _ = groups.flatMap{$0.filter { (item) -> Bool in
if item.contains(element) {
count = count + 1
return true
} else {
return false
}
}}
return count
}
findElementInMultiDimension(element: "Mexico")
print(findElementInMultiDimension(element: "Mexico")) //prints 1
Hope this helps :)
How to find the summation of all elements in 2d array in Swift?
One way is to use joined()
to flatten the array and then reduce
to sum it:
let my2dArray = [[01, 02, 03, 04],
[05, 06, 07, 08],
[09, 10, 11, 12],
[13, 14, 15, 16]]
let result = my2dArray.joined().reduce(0, +)
print(result) // 136
Note that my2dArray.joined()
doesn't create another array, but instead it creates a FlattenBidirectionalCollection<Array<Array<Int>>>
which allows sequential access to the items, both forwards and backwards, but it does not allocate new storage. You can of course do Array(my2dArray.joined())
if you wish to see how it looks in array format.
Multidimensional array to vector
You can use flatMap
for that.
let array1 = [[1], [2], [3]]
let result = array1.flatMap { $0 }
Output
[1, 2, 3]
Check Apple Documentation on flatMap
for more details.
Swift Filter Nested Array
let textToSearch:String = "some text"
for nestedArray in myArray {
for item:User in nestedArray
{
if user.name.contains(textToSearch) || user.userName.contains(textToSearch)
{
print("found")
}
}
}
How can I flatten an array swiftily in Swift?
There's a built-in function for this called joined
:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]].joined()
(Note that this doesn't actually return another Array, it returns a FlattenSequence
, but that usually doesn't matter because it's still a sequence that you can use with for
loops and whatnot. If you really care, you can use Array(arrayOfArrays.joined())
.)
The flatMap
function can also help you out. Its signature is, roughly,
flatMap<S: SequenceType>(fn: (Generator.Element) -> S) -> [S.Generator.Element]
This means that you can pass a fn
which for any element returns a sequence, and it'll combine/concatenate those sequences.
Since your array's elements are themselves sequences, you can use a function which just returns the element itself ({ x in return x }
or equivalently just {$0}
):
[[1, 2, 3], [4, 5, 6], [7, 8, 9]].flatMap{ $0 }
Related Topics
Swift: Programmatically Enumerate Outgoing Segues from a Uiviewcontroller
Wkwebview Auto Fill Login Form Swift 2
Accessor Gives the Wrong Value in Swift 1.2/2.0 Release Build Only
Core Data Predicate Not Working
How to Encode an Unmanaged<Seckey> to Base64 to Send to Another Server
Getting a Let Value Outside a Function
Swift: When Should I Use "Var" Instead of "Let"
Appending Tuples to an Array of Tuples
Get Signed Integer from Swift String of Binary
Scenedidload Being Called Twice
Swift: Floating Plus Button Over Tableview Using the Storyboard
How to Program a Nsoutlineview
Building a Spritekit/Gamekit Leaderboard Within a Specific Scene