Shubham bairagi
Shubham bairagi

Reputation: 953

Array iteration without using for loop is swift iOS

I have an array something Like:

let responseArray : [[String : Any]] = [["id": 1, "sub_array": [["id": 2, "sub_array": [["id": 3], ["id": 4]]],["id": 5, "sub_array": [["id": 6], ["id": 7]]]]], ["id": 8, "sub_array": [["id": 9], ["id": 10]]]]
print(responseArray as! NSArray)

and I want to merge it to show in UITableView

expecting the result like :

let expectedOutput : [[String : Any]] = [["id" : 1], ["id" : 2], ["id" : 3], ["id" : 4], ["id" : 5], ["id" : 6], ["id" : 7], ["id" : 8], ["id" : 9], ["id" : 10]]
print(expectedOutput as! NSArray)

I can achieve it by using loops, but how to do it without using a loop?

Upvotes: 1

Views: 2514

Answers (2)

Er.Gopal Vasani
Er.Gopal Vasani

Reputation: 448

Yes , You can . Swift CollectionTypes (Array , Dictionary , Set) has a massive good methods that provides a many alternative solution in compare of for-loop.

Here it is :-

We will perform 3 tasks as below :

  • First , We will fetch those ids that are not part of sub_array.
  • Second , We will fetch those ids that are the part of sub_array but not the part of inner sub_array.
  • Third and last one , We will fetch those ids that are part of sub_array's inner sub_array.

        let responseArray : [[String : Any]] = [["id": 1, "sub_array": [["id": 2, "sub_array": [["id": 3], ["id": 4]]],["id": 5, "sub_array": [["id": 6], ["id": 7]]]]], ["id": 8, "sub_array": [["id": 9], ["id": 10]]]]
    
        let arrExrernalIds = responseArray.flatMap({$0["id"] as? Int ?? 0})
        print(arrExrernalIds) // output :- [1, 8]
    
        let arrSub_ArrayIDs =   responseArray.flatMap({$0["sub_array"] as? [[String:Any]] ?? []}).flatMap({$0["id"] as? Int ?? 0})
    
        print(arrSub_ArrayIDs) // output :- [2, 5, 9, 10]
    
        let arrSubArray_SubArrayIDs = responseArray.flatMap({$0["sub_array"] as? [[String:Any]] ?? []}).flatMap({$0["sub_array"] as? [[String:Any]] ?? []}).flatMap({$0["id"] as? Int ?? 0})
    
        print(arrSubArray_SubArrayIDs) // output :- [3, 4, 6, 7]
    
        var allIDs = (arrExrernalIds + arrSub_ArrayIDs + arrSubArray_SubArrayIDs).sorted()
    
        print(allIDs) // output :- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    
        var expectedOutput = [[String:Any]]()
    
        for id in allIDs {
            expectedOutput.append(["id":id])
        }
    
        print(expectedOutput) // output :- [["id": 1], ["id": 2], ["id": 3], ["id": 4], ["id": 5], ["id": 6], ["id": 7], ["id": 8], ["id": 9], ["id": 10]]
    

Only 4 Lines of code and you can achieve your desired Array.

Upvotes: 1

Gereon
Gereon

Reputation: 17844

It's certainly possible to write a flatten function for this data structure without explicitly using for a in b loops, but given the nature of your data, loops and recursive calls are IMHO unavoidable.

func flatten(_ array: [[String: Any]]) -> [[String: Any]] {
    var result = [[String: Any]]()

    array.forEach { dict in
        dict.forEach { (key, val) in
            if let v = val as? [[String: Any]] {
                result.append(contentsOf: flatten(v))
            } else {
                result.append([key: val])
            }
        }
    }

    return result
}

Upvotes: 0

Related Questions