6

I have a list that I need to sort by "popularity" (more popular to less popular), this value comes from a JSON API. Is there a Sort function by given value in SwiftUI?

The JSON looks like this:

[
{
    "id": 1,
    "nombre": "The design of every day things",
    "autor": "Don Norman",
    "disponibilidad": true,
    "popularidad": 70,
    "imagen": "https://images-na.ssl-images-amazon.com/images/I/410RTQezHYL._SX326_BO1,204,203,200_.jpg"
},
{
    "id": 2,
    "nombre": "100 años de soledad",
    "autor": "Garcia Marquez",
    "disponibilidad": false,
    "popularidad": 43,
    "imagen": "https://images-na.ssl-images-amazon.com/images/I/51egIZUl88L._SX336_BO1,204,203,200_.jpg"
}
]

There's more to it, that's just a piece of it. Popularity is popularidad.

This is currently my list:

var body: some View {
    NavigationView {
        ScrollView {
            VStack(alignment: .leading) {
                ForEach(booksVM.books) { book in
                    HStack {
                        Text(book.nombre)
                        Spacer()
                    }
                    Text(book.autor)
                    Spacer()
                }
            }.padding(.leading, 5)
        }
    .navigationBarTitle("Bienvenido a la librería flux")
    .onAppear(perform: self.booksVM.fetchBooks)
    }
}

Please let me know if more code is needed to understand this.

1 Answer 1

11

You could use .sorted to sort your array.

Here is a simple example using your data. This will work if you try it in a playground.

let data = """
[
    {
        "id": 1,
        "nombre": "The design of every day things",
        "autor": "Don Norman",
        "disponibilidad": true,
        "popularidad": 70,
        "imagen": "https://images-na.ssl-images-amazon.com/images/I/410RTQezHYL._SX326_BO1,204,203,200_.jpg"
    },
    {
        "id": 2,
        "nombre": "100 años de soledad",
        "autor": "Garcia Marquez",
        "disponibilidad": false,
        "popularidad": 43,
        "imagen": "https://images-na.ssl-images-amazon.com/images/I/51egIZUl88L._SX336_BO1,204,203,200_.jpg"
    }
]
""".data(using: .utf8)!


struct Book: Codable {
    let id: Int
    let popularidad: Int
    let nombre: String
    let autor: String
    let disponibilidad: Bool
    let imagen: String
}

let decoder = JSONDecoder()
let books = try decoder.decode([Book].self, from: data)

let result = books.sorted {
    $0.popularidad > $1.popularidad
}

print(result)

You would just have to perform your sort before you use the array of books in the ForEach

So all you have to do is the following which will sort your array of Book objects.

ForEach(booksVM.books.sorted { $0.popularidad > $1.popularidad}) { book in
Sign up to request clarification or add additional context in comments.

6 Comments

But then I would have to hardcode each book. There are more books in the JSON. Probably should've said that.
You should be using Codable to convert your json into an array of Book objects. I have updated the example so that you can see how to do it.
Thanks, I was already using Codable. So all I needed was the ForEach line. Thank you so much!
What is booksVM.books...?
booksVM is an ObservedObject with an @Published property of books, where books is [Book].
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.