4

I'm new to Swift programming. For my particular project, I'm trying to filter a dictionary with some user input, and the dictionary's value consists of an array.

Here is some sample code, and what I'm trying to accomplish:

var dictionary = ["a": ["aberration", "abc"], "b" : ["babel", "bereft"]]

var filteredDictionary = [String: [String]]()

var searchText = "aberration"

//getting the first letter of string
var firstLetter = searchText[searchText.startIndex]

With this particular searchText, I'm trying to get:

filteredDictionary = ["a": ["aberration"]]

Edit: I want the dictionary to return with the first letter as its key, and the values with what searchText matches up with. Sorry if it I wasn't clear.

Here is some code I have tried, but obviously, I can't get it to work:

filteredDictionary = dictionary.filter{$0.key == firstLetter && for element in $0.value { element.hasPrefix(searchText) }}

Any help would be appreciated. Thanks.

3
  • 2
    What are you exactly you trying to filter? Commented Jan 4, 2018 at 5:50
  • I updated the question. I want to return a dictionary with the letter as its key, and the matching searchText as an array as its value. Commented Jan 4, 2018 at 17:30
  • The part you really need to clarify is what values in the array should be returned. It seems you want any word that has a prefix matching searchText but you don't make that clear (it's implied based on your code though). What if searchText is abe? Do you still want just aberration? What if searchText is ab? Do you want both aberration` and abc since both start with ab? Commented Jan 4, 2018 at 18:48

3 Answers 3

9

Here's a solution that maps the values based on the search and then filters out the empty results.

var dictionary = ["a": ["aberration", "abc"], "b" : ["babel", "bereft"]]
var searchText = "aberration"
let filteredDictionary = dictionary.mapValues { $0.filter { $0.hasPrefix(searchText) } }.filter { !$0.value.isEmpty }
print(filteredDictionary)

Output:

["a": ["aberration"]]

Sign up to request clarification or add additional context in comments.

3 Comments

As a followup question, how can you filter it so that it does not filter out the empty results, such that filteredDictionary keeps its keys? ["a": ["aberration"], "b" : [], "c" : [], "d" : [] ] etc.
Nevermind, I think I got it by getting rid of the last segment like so: filteredDictionary = dictionary.mapValues { $0.filter { $0.hasPrefix(searchText) } }
Correct, just drop the .filter { !$0.value.isEmpty } if you want to keep the empty keys.
2
let firstLetter = String(searchText[searchText.startIndex])
let filteredDictionary = dictionary
    .reduce(into: [String: [String]]()) { (result, object) in
        if object.key == firstLetter {
            let array = object.value.filter({ $0.hasPrefix(searchText) })
            if array.count > 0 {
                result[object.key] = array
            }
        }
    }

Output:

["a": ["aberration"]]

Comments

1

Try this:

    var dictionary = ["a": ["aberration", "abc"], "b" : ["babel", "bereft"]]
    var searchText = "aberration"
    var filteredDictionary = dictionary.filter { (key, value) -> Bool in
            return (value as! [String]).contains(searchText)
        }.mapValues { (values) -> [String] in
            return [searchText]
        }
    print(filteredDictionary)

You can use a combination of filter and map to achieve the desired result.

Output:

["a": ["aberration"]]

5 Comments

The values returned by this are not filtered as indicated in the question.
This still isn't correct since the search text needs to be a prefix and can match more than one value in each array.
It isn't mentioned anywhere in the question.
It's implied based on the use of hasPrefix in the question's code.
Requirements must be specified clearly in the question. Just adding the code isn't enough.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.