-1

I have an array of Super Hero objects. I want to group the superheroes based on the name property into separated arrays and then count how many objects are in each individual separated array

Object:

class SuperHero{
    var name: String?
    var power: Bool?
}

Array of superheroes (there can be an infinite num of superheroes)

var superHeroes = [SuperHero]()

let superHero1 = SuperHero()
superHero1.name = "SuperMan"
superHero1.power = true

superHeroes.append(superHero1)

let superHero2 = SuperHero()
superHero2.name = "BatMan"
superHero2.power = true

superHeroes.append(superHero2)

let superHero3 = SuperHero()
superHero3.name = "BatMan"
superHero3.power = true

superHeroes.append(superHero3)

let superHero4 = SuperHero()
superHero4.name = "SuperMan"
superHero4.power = true

superHeroes.append(superHero4)

//etc...

Use name property to sort:

let sortedHeros = superHeroes.sort{$0.name < $1.name}
for hero in sortedHeros{
    print(hero.name)
    /*
    prints
    BatMan
    BatMan
    SuperMan
    SuperMan
    */
}

How do I put the sorted array into separate arrays then print the count of each separated array?

//this is what I want
separatedArraysOfSuperHeroes = [[superHero2, superHero3], [superHero1, superHero4]]

//subscriprting isn't ideal because i'll never know the exact number of separated arrays
print(separatedArraysOfSuperHeroes[0].count)
print(separatedArraysOfSuperHeroes[1].count)

As per the comments the reason why I want sub arrays is because I want to use them to populate different tableview sections. For i.e. inside my tableview I would now have a 2 sections. The first section would have a header that says "Batman" with 2 Batman objects inside of it and the second section would have a header that says Superman with 2 Superman objects inside of it. The count property would show the number of super hero objects inside each section.

Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
  • Use `superHeroes.map` to create an array of superhero names and then put that array into an NSCountedSet. Job done – Paulw11 Mar 04 '17 at 12:47
  • 1
    Possible duplicate of [How to group by the elements of an array in Swift](http://stackoverflow.com/questions/31220002/how-to-group-by-the-elements-of-an-array-in-swift), or [Group elements of an array by some property](http://stackoverflow.com/questions/41564580/group-elements-of-an-array-by-some-property) – Martin R Mar 04 '17 at 12:54
  • You say you want the output to be `[[superHero2, superHero3], [superHero1, superHero4]]` That's an array of arrays, where you have 2 elements from your sorted array in the first sub-array, and then 2 other elements in the second sub-array. Why? What does that structure mean, other than an arbitrary grouping of your superhero objects? If you want a general-purpose solution you need to describe your goal in general terms rather than giving one example data-set and one example result. That's not enough information for us to deduce the process you want to use in order to get your results. – Duncan C Mar 04 '17 at 14:33
  • From the first part of your question I would think you would want your output to be `[name1, name2, name3, name4]` and `[power1, power2, power3, power4]` (A sorted array of names and a sorted array of power values from your SuperHero objects). But your stated desired output doesn't make any sense to me. – Duncan C Mar 04 '17 at 14:36
  • Please edit your question to state your goal clearly. As it is, we have to guess. – Duncan C Mar 04 '17 at 14:39
  • @Duncan C the reason why I want 2 different arrays is because inside my tableView i will display sections with the the superheroes names. For i.e. the first section will have a header that says "Batman" with the num of Batman objects(2). The second section will say "Superman" with the num of Superman objects(2). The reason why I didn't show all the code was because it seemed unnecessary. Wether the design is good or bad i want to show my superheroes inside their own sections. Basically I want the sub arrays to be used for the sections no matter how many sections there are. – Lance Samaria Mar 05 '17 at 01:13

1 Answers1

3
func getSeparatedArrayBasedOnName(superHeroes: [SuperHero]) -> [[SuperHero]] {

    guard let superNames = NSOrderedSet.init(array: superHeroes.map { $0.name ?? "" }).array as? [String] else {
        print("Something went wrong with conversion")
        return [[SuperHero]]()
    }

    var filteredArray = [[SuperHero]]()

    for superName in superNames {
        let innerArray = superHeroes.filter({ return $0.name == superName })
        filteredArray.append(innerArray)
    }

    for array in filteredArray {
        for hero in array {
            print(hero.name ?? "")
        }
    }

    return filteredArray
}
Ravi Aggarwal
  • 159
  • 1
  • 1
  • 10
  • Assuming you're right about the OPs desired output (an array of arrays grouped by superhero name) then your answer is a good one. I'm less clear on the OPs goal than you are, however, and would like to hear him state that goal clearly and coherently. – Duncan C Mar 04 '17 at 14:39
  • @Ravi Aggarwal thanks I will try it later and let you know – Lance Samaria Mar 05 '17 at 01:15
  • @RaviAggarwal this still works for me 3 yrs later :) – Lance Samaria May 31 '20 at 01:39