1

Recently I want to delete cells according to indexPaths, so the input parameter of the function is [IndexPath] type, I need to split the [IndexPath] to several arrays according to the indexPath.section, is there any easy way to do this? For example

indexPaths = 
[IndexPath(row: 0, section: 1),
 IndexPath(row: 1, section: 1), 
 IndexPath(row: 2, section: 1), 
 IndexPath(row: 2, section: 0)]

want to convert this to

indexPath1 = 
[IndexPath(row: 0, section: 1),
 IndexPath(row: 1, section: 1), 
 IndexPath(row: 2, section: 1)]

indexPath0 = 
[IndexPath(row: 2, section: 0)]

// maybe get a [Array]
[indexPath0, indexPath1]
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
whitekevin
  • 311
  • 3
  • 15
  • Please don't forget to indicate that your question has been successfully answered by clicking the checkmark to the left of the answer that best resolved your issue. You have not done this with any of your questions in all of the years you have been here. You should go back through all of your questions, and where appropriate, check an answer if it best resolved that question. – rmaddy Apr 27 '19 at 16:31

3 Answers3

3

One possible solution is to first build a dictonary where the keys are the section numbers and the values are the array of IndexPath in that section.

let indexPaths = [
    IndexPath(row: 0, section: 1),
    IndexPath(row: 1, section: 1),
    IndexPath(row: 2, section: 1),
    IndexPath(row: 2, section: 0),
]

let pathDict = Dictionary(grouping: indexPaths) { (path) in
    return path.section
}

Then you can map this dictionary into an array of the path arrays. But first sort those arrays by the section.

let sectionPaths = pathDict.sorted { (arg0, arg1) -> Bool in
    return arg0.key < arg1.key // sort by section
}.map { $0.value } // get just the arrays of IndexPath

print(sectionPaths)

Output:

[[[0, 2]], [[1, 0], [1, 1], [1, 2]]]

rmaddy
  • 314,917
  • 42
  • 532
  • 579
0
  • We need a HashMap, mapping over the key.
  • We need to sort the dictionary
  • We need to extract values of dictionary and append them to array
  • We need to return that array
var indexPaths = [IndexPath(row: 0, section: 1),
     IndexPath(row: 1, section: 1),
     IndexPath(row: 2, section: 1),
     IndexPath(row: 2, section: 0)
]

extension Array where Element == IndexPath {
    func splitArray() ->  Array<[IndexPath]> {
        var tempDict = [String : [IndexPath]]()
        for element in self {
            let section = element.section
            if tempDict[String(section)] != nil {
                // some element append
                if var array = tempDict[String(section)] {
                    array.append(element)
                    tempDict[String(section)] = array
                }

            } else {
                tempDict[String(section)] = [element]
            }
        }

        // dictionary mayn't have sorted, sort the dictionary 

        tempDict.sorted{ $0.key > $1.key }

        var returnedArray = Array<[IndexPath]>()
        for (key, value) in tempDict {
           returnedArray.append(value)
        }

        return returnedArray
    }
}

print(indexPaths.splitArray())

Ankur Lahiry
  • 2,253
  • 1
  • 15
  • 25
0

Use filter:

let indexPath0 = indexPaths.filter { $0.section == 0 }
let indexPath1 = indexPaths.filter { $0.section == 1 }
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
  • This doesn't scale. What if the original `indexPaths` has dozens of sections? You don't want a solution that creates individual variables for each section. – rmaddy Apr 27 '19 at 15:04
  • 1
    What if it hasn’t? This is just quick answer to the question and of course it’s not the most efficient and scalable one. Thanks for mentioning that. – Mojtaba Hosseini Apr 27 '19 at 15:08