Remove item that is inside of an array which is the value in a dictionary Swift 2

后端 未结 3 397
余生分开走
余生分开走 2021-01-25 01:38

I know this might have been answered before, but I couldn\'t find anything when i searched.

So i have a dictionary that looks like this:

var dict = [Stri         


        
相关标签:
3条回答
  • 2021-01-25 02:02
    guard var furniture = dict["Furniture"] else {
        //oh shit, there was no "Furniture" key
    }
    furniture.removeAtIndex(1)
    dict["Furniture"] = furniture
    
    0 讨论(0)
  • 2021-01-25 02:10

    Many answers that cover the mutation of dictionary entries tend to focus on the remove value -> mutate value -> replace value idiom, but note that removal is not a necessity. You can likewise perform an in-place mutation using e.g. optional chaining

    dict["Furniture"]?.removeAtIndex(1)
    
    print(dict)
        /* ["Furniture": ["Table", "Bed"], 
            "Food": ["Pancakes"]]          */
    

    Note however that using the .removeAtIndex(...) solution is not entirely safe, unless you perform an array bounds check, making sure that the index for which we attempt to remove an element actually exists.

    As a safe in-place-mutation alternative, use the where clause of an optional binding statement to check the the index we want to remove is not out of bounds

    let removeElementAtIndex = 1
    if let idxs = dict["Furniture"]?.indices where removeElementAtIndex < idxs.endIndex {
        dict["Furniture"]?.removeAtIndex(removeElementAtIndex)
    }
    

    Another safe alternative is making use of advancedBy(_:limit) to get a safe index to use in removeAtIndex(...).

    let removeElementAtIndex = 1
    if let idxs = dict["Furniture"]?.indices {
        dict["Furniture"]?.removeAtIndex(
            idxs.startIndex.advancedBy(removeElementAtIndex, limit: idxs.endIndex))
    }  
    

    Finally, if using the remove/mutate/replace idiom, another safe alternative is using a flatMap for the mutating step, removing an element for a given index, if that index exists in the array. E.g., for a generic approach (and where clause abuse :)

    func removeSubArrayElementInDict<T: Hashable, U>(inout dict: [T:[U]], forKey: T, atIndex: Int) {
        guard let value: [U] = dict[forKey] where
            { () -> Bool in dict[forKey] = value
                .enumerate().flatMap{ $0 != atIndex ? $1 : nil }
                return true }()
            else { print("Invalid key"); return }
    }
    
    /* Example usage */
    var dict = [String:[String]]()
    dict = ["Furniture": ["Table", "Chair", "Bed"], "Food": ["Pancakes"]]
    
    removeSubArrayElementInDict(&dict, forKey: "Furniture", atIndex: 1)
    
    print(dict)
        /* ["Furniture": ["Table", "Bed"], 
            "Food": ["Pancakes"]]          */
    
    0 讨论(0)
  • 2021-01-25 02:25

    If you want to remove specific element, you could do this:

    var dict = ["Furniture": ["Table", "Chair", "Bed"], "Food": ["Pancakes"]]
    
    extension Array where Element: Equatable {
        mutating func removeElement(element: Element) {
            if let index = indexOf ({ $0 == element }) {
                removeAtIndex(index)
            }
        }
    }
    
    dict["Furniture"]?.removeElement("Chair") //["Furniture": ["Table", "Bed"], "Food": ["Pancakes"]]
    
    0 讨论(0)
提交回复
热议问题