5

i have a struct array that i want "break up" into smaller arrays that can be called as needed or at least figure out how i can map the items needed off one text value.

the struct:

struct CollectionStruct {
    var name : String
    var description : String
    var title : String
    var image : PFFile
    var id: String
}

and the array made from the struct

var collectionArray = [CollectionStruct]()

var i = 0
for item in collectionArray {
    print(collectionArray[i].name)    
    i += 1  
}

printing partArray[i].name gives the following result:

pk00_pt01
pk00_pt02
pk00_pt03
pk01_pt01
pk01_pt02
pk01_pt03
pk01_pt04
pk01_pt05
pk01_pt06
pk01_pt07
pk01_pt08

this is just some test values but there could be thousands of entries here so i wanted to filter the entire array just by the first 4 characters of [i].name i can achieve this by looping through as above but is this achievable using something like .map?

4
  • 1
    var partArray = collectionArray.map{$0.name} then ... print(partArray) Commented Jan 10, 2017 at 21:55
  • What exactly do you mean by "i wanted to filter the entire array just by the first 4 characters of [i].name"? You want to get an array of strings of the first 4 characters of each name of each element? Commented Jan 10, 2017 at 21:58
  • 2
    Also your for loop can be expressed as just for item in collectionArray { print(item.name) } Commented Jan 10, 2017 at 22:01
  • Are you showing us all the code above? It seems like some is missing such as where you are filtering based on the first 4 characters? You may be looking for Swift's filter function but your question is unclear Commented Jan 10, 2017 at 22:03

3 Answers 3

5

I wanted to filter the entire array just by the first 4 characters of [i].name

You can achieve this by filtering the array based on the substring value of the name, as follows:

let filteredArray = collectionArray.filter {
    $0.name.substring(to: $0.name.index($0.name.startIndex, offsetBy: 4)).lowercased() == "pk00"
    // or instead of "pk00", add the first 4 characters you want to compare
}

filteredArray will be filled based on what is the compared string.

Hope this helped.

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

1 Comment

Glad to help, btw there is even a shorter solution (as @Hamish suggested), by using hasPrefix(_:), but that won't be 100% accurate for comparing only the first four characters.
2

If you want to group all data automatically by their name prefix. You could use a reducer to generate a dictionary of grouped items. Something like this:

let groupedData = array.reduce([String: [String]]()) { (dictionary, myStruct) in
    let grouper = myStruct.name.substring(to: myStruct.name.index(myStruct.name.startIndex, offsetBy: 4))
    var newDictionart = dictionary
    if let collectionStructs = newDictionart[grouper] {
        newDictionart[grouper] = collectionStructs + [myStruct.name]
    } else {
        newDictionart[grouper] = [myStruct.name]
    }
    return newDictionart
}

This will produce a dictionary like this:

[
    "pk00": ["pk00_pt01", "pk00_pt02", "pk00_pt03"],
    "pk01": ["pk01_pt01", "pk01_pt02", "pk01_pt03", "pk01_pt04", "pk01_pt05", "pk01_pt06", "pk01_pt07"],
    "pk02": ["pk02_pt08"]
]

2 Comments

I struggle understanding the shorthand syntax like $0 ect. So this is a nice way of getting the result.
Yeah, in this case shorthand syntax could be hard to read. And additionally the complexity to generate this dictionary is linear O(n) but to read the sliced arrays will be a constant O(1) complexity. With filter you always will had an O(n) complexity with default search.
0

Not sure if i am understanding you correctly but it sounds like you are looking for this...

To create a new array named partArray from an already existing array named collectionArray (that is of type CollectionStruct) you would do...

var partArray = collectionArray.map{$0.name}

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.