Home > Blockchain >  How can I remove duplicate elements from a list in SwiftUI
How can I remove duplicate elements from a list in SwiftUI

Time:07-04

I can't put the categories variable anywhere in ConsoleList as I always get an error. I get: "Value of type '[AnyHashable : Any]' has no member 'category'"

import Foundation

let imgName: String  = ""
let consoleName: String = ""
let description: String = ""
let initialPrice: Double = 0.00
let ReleaseDate: String = ""
let Discontinuation: Int = 0
let category: String = ""

struct consoleList{
    
  let categories = Dictionary(grouping: consoles, by: {$0.category } )
    
    let consoles = [
        
        [imgName: "FAMICOM",
                       consoleName: "Famicom",
                       description: "It was released in 1983 in Japan and due to it success it gave birth to the NES",
                       initialPrice: 179,
                       ReleaseDate: "Release Date: July 15, 1983",
                       Discontinuation: 2003,
                       category: "Home Consoles"],
        [imgName: "NES",
                       consoleName: "NES",
                       description: "It was released in 1985 in the US and EU and was the european version of the Famicom",
                       initialPrice: 179,
                       ReleaseDate: "Release Date: Oct 18, 1985",
                       Discontinuation: 1991,
                       category: "Home Consoles"],
        [imgName: "US_SNES",
                       consoleName: "SNES, Super Famicom",
                       description: "Nintendo released the Super Nintendo Entertainment System, a redesigned version of the Super Famicom, in North America for US$199 (equivalent to $400 in 2021).",
                       initialPrice: 199,
                       ReleaseDate: "Release Date: Sept 9, 1991",
                       Discontinuation: 1999,
                       category: "Home Consoles"],
        [imgName: "GB_FAT",
                       consoleName: "Original GameBoy",
                       description: "The Game Boy is the first handheld in the Game Boy family, it was first released in Japan on April 21, 1989.",
                       initialPrice: 89.99,
                       ReleaseDate: "Release Date: Apr 21, 1989",
                       Discontinuation: 200,
                       category: "Handheld Consoles"],
        [imgName: "GB_POCKET",
                       consoleName: "GameBoy Pocket",
                       description: "On July 21, 1996, Nintendo released the Game Boy Pocket for US$69.99: a smaller, lighter unit that required fewer batteries. It has space for two AAA batteries, which provide approximately 10 hours of gameplay.",
                       initialPrice: 69.99,
                       ReleaseDate: "Release Date: Jul 21, 1996",
                       Discontinuation: 2003,
                       category: "Handheld Consoles"],
        [imgName: "GB_LIGHT",
                       consoleName: "Release Date: GameBoy Light",
                       description: "The Game Boy Light is the second and final revision of the original Game Boy exclusive to Japan.",
                       initialPrice: 89.99,
                       ReleaseDate: "Release Date: Apr 14, 1998",
                       Discontinuation: 2003,
                       category: "Handheld Consoles"]
        
        ]
    
   
 
}


In my content view preview, I get the two categories I want but they are duplicated by the amount of consoles the category belongs to and I just want one of each, anything I can do?

import SwiftUI
let Con :[consoleDetails] = consoleList.Consoles
struct ContentView: View {
    var body: some View {
        NavigationView{
            List(consoleList.categories.sorted(by: {$0.key > $1.key}), id:\.key){con in
                NavigationLink(destination: ConsoleSection(), label:{
                    Image(systemName: "folder.fill")
                        .scaledToFit()
                        .frame(height: 30)
                        .cornerRadius(4)
                        .padding(.vertical, 4)
                    VStack{
                        Text(con.key)
                        
                    }
                }).navigationTitle("appname")

            }
        }
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


CodePudding user response:

The error is pretty simple. This is not a list of console categories it is a list of ConsoleDetails and you are showing the console category. That´s why you see doublets and triplets.

If you want to show a list of consoles and their respective names change:

Text(con.category)

to:

Text(con.consoleName)

If you really want a List of console categories you would need to group your ConsoleDetail into a Dictionary of type [String:[Consoledetail]]. This could be used to iterate in the list and show them.

Add this to your ConsoleList:

static let categories = Dictionary(grouping: consoles, by: {$0.category } )

Your ContentView then should look like this:

var body: some View {
    NavigationView{
        List(ConsoleList.categories.sorted(by: {$0.key > $1.key}), id:\.key){con in
            NavigationLink(destination: ConsoleSection(), label:{
                Image(systemName: "folder.fill")
                    .scaledToFit()
                    .frame(height: 30)
                    .cornerRadius(4)
                    .padding(.vertical, 4)
                VStack{
                    Text(con.key)
                    
                }
            }).navigationTitle("appname")

        }
    }
}

Remarks:

  • You got your naming the wrong way around. In Swift you name classes and struct uppercased and properties lowercased.
  • ConsoleSection will probably need the list of ConsoleDetail that is grouped in con in this case.

Edit:

You can´t access a nonstatic property from a static one. Either remove the static keyword from categories property or add it back to your consoles property.

E.g.:

static let categories = Dictionary(grouping: consoles, by: {$0.category } )

static let consoles = [...

Edit:

Your ConsoleList should look like this:

struct ConsoleList{
    
    static let categories = Dictionary(grouping: consoles, by: {$0.category } )
    
    static let consoles = [
        
        ConsoleDetails(imgName: "FAMICOM",
                       consoleName: "Famicom",
                       description: "It was released in 1983 in Japan and due to it success it gave birth to the NES",
                       initialPrice: 179,
                       ReleaseDate: "Release Date: July 15, 1983",
                       Discontinuation: 2003,
                       category: "Home Consoles"),
        ConsoleDetails(imgName: "NES",
                       consoleName: "NES",
                       description: "It was released in 1985 in the US and EU and was the european version of the Famicom",
                       initialPrice: 179,
                       ReleaseDate: "Release Date: Oct 18, 1985",
                       Discontinuation: 1991,
                       category: "Home Consoles"),
        ConsoleDetails(imgName: "US_SNES",
                       consoleName: "SNES, Super Famicom",
                       description: "Nintendo released the Super Nintendo Entertainment System, a redesigned version of the Super Famicom, in North America for US$199 (equivalent to $400 in 2021).",
                       initialPrice: 199,
                       ReleaseDate: "Release Date: Sept 9, 1991",
                       Discontinuation: 1999,
                       category: "Home Consoles"),
        ConsoleDetails(imgName: "GB_FAT",
                       consoleName: "Original GameBoy",
                       description: "The Game Boy is the first handheld in the Game Boy family, it was first released in Japan on April 21, 1989.",
                       initialPrice: 89.99,
                       ReleaseDate: "Release Date: Apr 21, 1989",
                       Discontinuation: 200,
                       category: "Handheld Consoles"),
        ConsoleDetails(imgName: "GB_POCKET",
                       consoleName: "GameBoy Pocket",
                       description: "On July 21, 1996, Nintendo released the Game Boy Pocket for US$69.99: a smaller, lighter unit that required fewer batteries. It has space for two AAA batteries, which provide approximately 10 hours of gameplay.",
                       initialPrice: 69.99,
                       ReleaseDate: "Release Date: Jul 21, 1996",
                       Discontinuation: 2003,
                       category: "Handheld Consoles"),
        ConsoleDetails(imgName: "GB_LIGHT",
                       consoleName: "Release Date: GameBoy Light",
                       description: "The Game Boy Light is the second and final revision of the original Game Boy exclusive to Japan.",
                       initialPrice: 89.99,
                       ReleaseDate: "Release Date: Apr 14, 1998",
                       Discontinuation: 2003,
                       category: "Handheld Consoles")]
    
}
  • Related