Determining which array a string came from

79 Views Asked by At

I have 3 Animal Arrays:

let mammals = ["Dog", "Cat", "Bear"]
let fish = ["Clownfish", "Seahorse", "Scorpion Fish"]
let reptiles = ["Chameleon", "Snake", "Lizard"]

A button generates an animal at random, and then appends it to an allAnimals array. I'd like to be able to determine WHICH array the string (animal) came from.

I tried working with

allAnimals.contains()

however that explicitly takes a var as an argument. I can do allAnimals.contains("Seahorse") just fine. But I need to be able to check all arrays.

I also tried iterating through the array.

for i in allAnimals {
  if i.contains(mammals){ print("Came from the Mammal array") }
  else if i.contains(fish){ print("Came from the Fish array") }
  else if i.contains(reptiles){ print("Came from the Reptiles array") }
}

That threw the error:

Cannot convert value of type '[String]' to expected argument type 'String'

How can I determine which array the random string came from?

4

There are 4 best solutions below

1
On BEST ANSWER

The other way round

for anAnimal in allAnimals { // with a bit more descriptive index variable
  if mammals.contains(anAnimal){ print("Came from the Mammal array") }
  else if fish.contains(anAnimal){ print("Came from the Fish array") }
  else if reptiles.contains(anAnimal){ print("Came from the Reptiles array") }
}
0
On

A cleaner protocol approach (Swift 3)

So basically as others have suggested... Using the array to determine which group it belongs to is not really proper design. However, if its something very simple and you know for sure it won't need to be extended, your approach might actually be just fine.

protocol Animal: CustomStringConvertible {
    var description: String { get }
}
protocol Mammal: Animal {}
protocol Fish: Animal {}
protocol Reptile: Animal {}

class Dog: Mammal { var description: String = "Dog" }
class Cat: Mammal { var description: String = "Cat" }
class Bear: Mammal { var description: String = "Bear" }

class Clownfish: Fish { var description: String = "Clownfish" }
class Seahorse: Fish { var description: String = "Seahorse" }
class ScorpionFish: Fish { var description: String = "Scorpion Fish" }

class Chameleon: Reptile { var description: String = "Chameleon" }
class Snake: Reptile { var description: String = "Snake" }
class Lizard: Reptile { var description: String = "Lizard" }

let everyAnimal:[Animal] = [Dog(), Cat(), Bear(), Clownfish(), Seahorse(), ScorpionFish(), Chameleon(), Snake(), Lizard()]
let fish = everyAnimal.filter({$0 is Fish})
print(fish)
// Clownfish, Seahorse, Scorpion Fish
let mammals = everyAnimal.filter({$0 is Mammal})
print(mammals)
// Dog, Cat, Bear
let reptiles = everyAnimal.filter({$0 is Reptile})
print(reptiles)
// Chameleon, Snake, Lizard
0
On

You need to check if each array contains the randomly selected animal.

let mammals = ["Dog", "Cat", "Bear"]
let fish = ["Clownfish", "Seahorse", "Scorpion Fish"]
let reptiles = ["Chameleon", "Snake", "Lizard"]

let chosenAnimal = "Cat"

if mammals.contains(chosenAnimal) {
    print("mammal")
} else if fish.contains(chosenAnimal) {
    print("fish")
} else if reptiles.contains(chosenAnimal) {
    print("reptile")
} else {
    print("animal not in any arrays")
}
0
On

You could define an enum with your different animal types, and construct arrays of that enum animal type, where the associated value of each case in the enum (String) gives the details of the animal.

E.g.

enum Animal: CustomStringConvertible {
    case mammal(String)
    case fish(String)
    case reptile(String)

    var description: String {
        switch self {
        case .mammal: return "Mammal"
        case .fish: return "Fish"
        case .reptile: return "Reptile"
        }
    }

    var species: String {
        switch self {
        case .mammal(let s), .fish(let s), .reptile(let s): return s
        }
    }
}

Example usage:

let mammals = ["Dog", "Cat", "Bear"].map(Animal.mammal)
let fish = ["Clownfish", "Seahorse", "Scorpion Fish"].map(Animal.fish)
let reptiles = ["Chameleon", "Snake", "Lizard"].map(Animal.reptile)

let allAnimals = [reptiles[2], mammals[1]]

for animal in allAnimals {
    print("\(animal.species) is a \(animal)")
} /* Lizard is a Reptile
     Cat is a Mammal     */