简体   繁体   中英

same value in dictionary in swift

I m mapping data that come from service with using dictionary [String: String]. I collect them dictionary array. For example, if their parent ids are the same, I want to add their values by array value.

["ParentId": "1","Value": "["Giyim","Aksesuar","Ayakkabı"]"]

It is also the reason I don't know parent id sometimes on the left sometimes on the right in photo

Here is my code and its output.

struct Categories {

    let parentId: String
    let values: [String]

}

                for result in results {

                    if result?.parentCategoryId != "" {
                        
                        for docId in self.docIds {
                            
                            if result?.parentCategoryId == docId {
                                
                                //print(result?.name)
                                var values = [String]()
                                values.append(result?.name ?? "")
                                
                                self.newCat.append(Categories(parentId: docId, values: values))
                                
                            }
                        }
                        
                    }
                }

编辑过的图片

Problem

As far as I understand from the description you want to map some service data structure to a dictionary where key is parentId and value is an array of some items referred to parentId.

I believe your problem comes from a misunderstanding of the concept of dictionary as a data structure. [String: String] is dictionary where keys and their associated values are of String type. For example:

["firstKey": "firsthValue", "secondKey": "secondValue", ...]

That means you cannot store associated values of String and Array types in the same dictionary , as you already told the compiler you would like to store only strings.

It is also the reason I don't know parent id sometimes on the left sometimes on the right in photo

This is because key-value pairs are stored in the dictionary without order. This is how dictionaries work:) I'd strongly recommend reading some short official materials to get used to them.

  • New Swift 5.4 version has a new OrderedDictionary data structure, where keys are ordered, but there is absolutely 100500% no reason to use it for your problem*

Possible solutions

In your case i would suggest either use some struct:

struct SomeData {
    let parentID: Int
    var values: [String]
}

var storage: [SomeData] // alternative to emptyDic

// Filling storage with data from service
for result in inputData {
    // search for SomeData with required id, add value
    // OR create SomeData if there is no such id in array yet
}

OR [personally this appeals to me more]

Store data in [String: [String]] dictionary, where the key is parentID and the associated value is an array of values. The algorithm of filling this dictionary is pretty the same:

  1. You add new key-value pair for every new parentID
  2. You append new values for parentIDs that are already in the dictionary.

Using the struct approach, you could do something like this (you'll need to adapt it to your code, but that should be straightforward):

struct Categories {
    let parentId: String
    var values: [String] //notice this needs to be a var, not a let
}

func addItem(categories : inout [Categories], docId: String, name: String) {
        if let index = categories.firstIndex(where: { $0.parentId == docId }) {
            categories[index].values.append(name)
        } else {
            categories.append(Categories(parentId: docId, values: [name]))
        }
}

func addValues() {
  var categories = [Categories]()
  addItem(categories: &categories, docId: "4", name: "Test1")
  addItem(categories: &categories, docId: "1", name: "Test")
  addItem(categories: &categories, docId: "4", name: "Test2")
  addItem(categories: &categories, docId: "4", name: "Test3")
  print(categories)

  //in your code, it'll look more like:
  // addItem(categories: &self.newCat, docId: docId, name: result?.name ?? "")
} 

Which yields this:

[
  StackOverflowPlayground.Categories(parentId: "4", values: ["Test1", "Test2", "Test3"]), 
  StackOverflowPlayground.Categories(parentId: "1", values: ["Test"])
]

I still wonder whether you maybe just want a Dictionary that is keyed by the parentId , but not knowing your use case, it's hard to say.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM