skip to Main Content

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))
                                
                            }
                        }
                        
                    }
                }

edited picture

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search