0

I have defined a struct as follows :

struct ECUnifiedStructure{

var contactName             : String!
var contactNumber           = [String]()
...
...

init(contact: CNContact , EProfile : Bool) {
    let validTypes = [
        CNLabelPhoneNumberiPhone,
        CNLabelPhoneNumberMobile,
        CNLabelPhoneNumberMain,
        CNLabelHome,
        CNLabelWork
    ]

    var givenName           = contact.givenName + " " + contact.middleName
    let familyName          = contact.familyName
    if (givenName == "" && familyName == "") || givenName == " "{
        givenName           = contact.organizationName
    }

    self.contactName = givenName.capitalized + familyName.capitalized
    self.contactNumber = contact.phoneNumbers.compactMap({ (PhoneNumber) -> String? in
        if let phoneLabel  = PhoneNumber.label , validTypes.contains(phoneLabel){
            return PhoneNumber.value.stringValue.replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "-", with: "")
        }
        return nil
    })
....
....
....
}}

Problem Statement : Need to filter an array of ECUnifiedStructure (ie . [ECUnifiedStructure]) based upon name and phone Number(check both substring and string as whole).

Current Implementation : The following is the current implementation I have done. Here both contacts and filter contacts are [ECUnifiedStructure].

self.filterContacts = self.contacts.filter {($0.contactName).range(of: textString, options: [ .caseInsensitive, .diacriticInsensitive ]) != nil} + self.contacts.filter {($0.contactNumber.compactMap {$0}.contains(textString))}

Issues with implementation : Getting result for filtering contact name as intended with results including both string as whole and substrings but

when filtering phone number , result for substrings not found . Only when we give whole phone number does the result turn up.

Probable cause :

self.contacts.filter {($0.contactNumber.compactMap {$0}.contains(textString))}

Eg : Suppose contacts = [[name: "David" , phoneNumber : ["1234567890",9876543210]], [name: "Hilton" , phoneNumber : ["1011111111","2222222222"]] , [name: "lewis" , phoneNumber : ["1111111111","2222222222"]]]

searchString = "10"

intended result = [[name: "David" , phoneNumber : ["1234567890",9876543210]], [name: "Hilton" , phoneNumber : ["1011111111","2222222222"]]]

current Result = empty.

Please propose an elegant way of doing it.If you can please point out what I did wrong . Thanks in advance.

1
  • yes, I have tried it. @ArashEtemad Commented Mar 7, 2019 at 9:56

1 Answer 1

1

This will return any struct object that has a phonenumber containing "10"

let result = contacts.filter{ $0.phoneNumber.contains(where: { $0.contains("10")}) }

Using your original filter code

self.filterContacts = self.contacts.filter {($0.contactName).range(of: textString, options: [ .caseInsensitive, .diacriticInsensitive ]) != nil} + self.contacts.filter { $0.contactNumber.contains(where: {$0.contains(textString)})}

Here is my complete test code

struct ECUnifiedStructure{
    var name          : String!
    var phoneNumber   = [String]()
}

let contacts:[ECUnifiedStructure] = [ECUnifiedStructure(name: "David" , phoneNumber : ["1234567890","9876543210"]), 
     ECUnifiedStructure(name: "Hilton" , phoneNumber : ["1011111111","2222222222"]) , 
     ECUnifiedStructure(name: "lewis" , phoneNumber : ["1111111111","2222222222"])]

let result = contacts.filter{ $0.phoneNumber.contains(where: { $0.contains("10")}) }

for r in result {
    print(r)
}

output

ECUnifiedStructure(name: Optional("David"), phoneNumber: ["1234567890", "9876543210"])
ECUnifiedStructure(name: Optional("Hilton"), phoneNumber: ["1011111111", "2222222222"])
Sign up to request clarification or add additional context in comments.

Comments

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.