RajeshKumar R
RajeshKumar R

Reputation: 15748

Remove dictionary from array where value is empty string (Using Higher Order Functions)

I have a Array of dictionary

    var details:[[String:String]] = [["name":"a","age":"1"],["name":"b","age":"2"],["name":"c","age":""]]
    print(details)//[["name": "a", "age": "1"], ["name": "b", "age": "2"], ["name": "c", "age": ""]]

Now I want to remove dictionary from array where value is empty string. I've achieved this with a nested for loop.

    for (index,detail) in details.enumerated()
    {
       for (key, value) in detail
       {
        if value == ""
        {
            details.remove(at: index)
        }
       }
    }
    print(details)//[["name": "a", "age": "1"], ["name": "b", "age": "2"]]

How can I achieve this with Higher Order Functions(Map, filter, reduce and flatMap)

Upvotes: 0

Views: 6576

Answers (3)

Mr. Hedgehog
Mr. Hedgehog

Reputation: 986

You can try:

let filtered = details.filter { !$0.values.contains { $0.isEmpty }}

This is also independent from the internal dictionary structure (like name of the keys)

Upvotes: 1

dfrib
dfrib

Reputation: 73186

Based on your for loop, it seems you want to remove dictionaries from details if any key-value pair therein contains an empty String, "", as a value. For this, you could e.g. apply filter on details, and as a predicate to the filter, check the values property of each dictionary for the non-existance of "" (/non-existance of an empty String). E.g.

var details: [[String: String]] = [
    ["name": "a", "age": "1"],
    ["name": "b", "age": "2"],
    ["name": "c", "age": ""]
]

let filteredDetails = details.filter { !$0.values.contains("") }
print(filteredDetails)
/* [["name": "a", "age": "1"], 
     "name": "b", "age": "2"]] */

or,

let filteredDetails = details
    .filter { !$0.values.contains(where: { $0.isEmpty }) }

On another note: seeing you use an array of dictionaries with a few seemingly "static" keys, I would advice you to consider using a more appropriate data structure, e.g. a custom Struct. E.g.:

struct Detail {
    let name: String
    let age: String
}

var details: [Detail] = [
    Detail(name: "a", age: "1"),
    Detail(name: "b", age: "2"),
    Detail(name: "c", age: "")
]

let filteredDetails = details.filter { !$0.name.isEmpty && !$0.age.isEmpty }
print(filteredDetails)
/* [Detail(name: "a", age: "1"),
    Detail(name: "b", age: "2")] */

Upvotes: 7

Nishant Bhindi
Nishant Bhindi

Reputation: 2252

You can use the filter method of array as below.

let arrFilteredDetails = details.filter { ($0["name"] != "" || $0["age"] != "")}

Thanks

Upvotes: 3

Related Questions