Not Hashable when the Struct is

So it’s claiming my struct isn’t listed as Hashable when it is… Basically, trying to make the day appear, then the entre. I’ve tried other methods like 2 ForEach’s but that just makes it wrong… I’ve tried initializing storeData in the List, but again, has the wrong effect.

struct RestaurantItem: Identifiable, Hashable, Codable {
    var id = UUID()
    var name: String
    var note = ""
    
    enum CodingKeys: String, CodingKey {
        case name
        case note
    }

No, it’s saying the tuple (String, RestaurantItem) is not Hashable. Tuples are not Hashable and you can’t make them Hashable.

What exactly are you trying to do? It’s not entirely clear from your code what you expect the outcome to be. That would be helpful to figure out what kind of solution to suggest.

Ultimately I’ll want to display data in a calendar and list. I have they days of the week setup, then below it will have an entre. Basically puts the thinking aside for what meals to have that week type of thing.

Later on I’ll do another randomizer for local restaurants… when my wife was pregnant she never knew what to eat. Didn’t care either, and neither did I. I’d like to make an app that puts the thinking aside, essentially :slight_smile:

Since tuples aren’t Hashable, you can’t use \.self as the id for your List. You can, however, use one of the elements in the tuple as the id, provided it is unique in the array you are looping through.

I’m still not 100% clear on what you are expecting to see in this particular View, but here is a very simple example that should illustrate a way forward for you:

struct ZipperedList: View {
    let days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
    //I don't have your RestaurantItem data to use, so let's just use Strings
    let entrees = ["Fish", "Shrimp", "Tacos", "Pizza", "Thai", "Burgers", "Steak", "Quinoa", "Chili", "Breakfast"]
   
    @State private var meals: [(String, String)] = []
    
    var body: some View {
        VStack {
            Text("Pull down to refresh list").font(.caption)
            List(meals, id: \.0) { (day, entree) in 
            //\.0 refers to the first element in the tuple, i.e., the day
                VStack(alignment: .leading) {
                    Text(day).bold().font(.title)
                    Text(entree).font(.title3)
                }
            }
            .refreshable {
                shuffleMeals()
            }
        }
        .onAppear {
            shuffleMeals()
        }
    }
    
    func shuffleMeals() {
        meals = Array(zip(days, entrees.shuffled()))
    }
}
2 Likes

Yep this is the idea I was going for! Thank you for your help, and your time!

Hey so a follow up…

[{"name":"Taco’s","note":""},
{"name":"Enchiladas","note":""},
{"name":"Sushi","note":""},
{"name":"Soup","note":""}]

Feel like I really should know how to do this… frustrated in fact how slow I am with this… feel like I should be a lot better. Anyways, trying to figure out how to initialize storeData.restaurantList so I can see the name’s.

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

   func shuffleMeals() {
 meals = Array(zip(days, storeData.restaurantList.shuffled()))
}

Your data definition is a struct called RestaurantItem so when you want to create an array of those items you have to create an instance of RestaurantItem for each of the items you want in the array. In Playground this is an example of what you would do:

struct RestaurantItem: Identifiable, Hashable, Codable {
    var id = UUID()
    var name: String
    var note: String

    enum CodingKeys: String, CodingKey {
        case name
        case note
    }
}

var items = [
    RestaurantItem(name: "Tacos", note: ""),
    RestaurantItem(name: "Enchiladas", note: ""),
    RestaurantItem(name: "Sushi", note: ""),
    RestaurantItem(name: "Soup", note: "")
]

for item in items {
    print(item)
}

When you run that code this is what you would see:

RestaurantItem(id: C05314A2-1DE3-4B51-AE80-BC4906BE52F3, name: "Tacos", note: "")
RestaurantItem(id: 1E246D47-002B-4AC8-ADA5-FA7DE4CC4EA1, name: "Enchiladas", note: "")
RestaurantItem(id: 9925ADAC-1C03-4E40-A359-5113FF3429FD, name: "Sushi", note: "")
RestaurantItem(id: 1CF04D10-A52A-42ED-8043-8A00BA40A713, name: "Soup", note: "")

Roosterboy’s option works great, it’s just that the info is in a json inside the app. When calling sourceData.restaurantList in foreach, it lets me see the list when I do text(.name)

ForEach(storeData.restaurantList) { food in
Text(food.name)
}

Just as a matter of interest, what does your overall json file look like?

This was my JSON file. this is what it currently, creates

[{"name":"Taco’s","note":""},
{"name":"Enchiladas","note":""},
{"name":"Sushi","note":""},
{"name":"Soup","note":""}]

1 Like

On the bottom it says Add/Remove Restaurants… When I was deciding the intent of the app, it was related to restaurants.
When my wife was pregnant, we both never knew what we wanted to eat. So it’d be same concept: List restaurants that actually normally interest you/go to, and then it was gonna be randomized. Now I’m trying to figure out how to get this concept to work for a week schedule for meals. Having a family of 6, you wanna do the least amount of thinking. This would be one way.

So, should I know how to be doing this? …I feel like for where I should be at, I should know how to do this… not to mention, I keep asking how-to questions. I know that exists and that’s what stack overflow’s for, but I feel like these are “basic” questions