@SwiftRabbit may have overload confusion. Let's simplify.
Creating a single String from SwiftData query (.map?, .reduce?, .joined?)
You may be looking for ONE coding solution but from your message title you're mashing a few different concepts: SwiftData, Strings,
and Arrays
.
Everything I've searched on the web is 6 or 7 years old
False! @twoStraws updated his articles and videos this fall, and continues to do so!
ADVERT: 100 Days of SwiftUI
This website has excellent tutorials on SwiftData, Strings,
AND Arrays
. However, it seems you're not following the 100 Days of SwiftUI tutorials? If so, you could let us know which day you're on, which video you watched, and which concept you may be stuck on.
Break your Big Problem into smaller solvable problems.
This bit of code grabs data from SwiftData
and stuffs it into an array. Because it's SwiftData, if any data in your datastore changes, this array will be automagically updated.
// Grab data from SwiftData. Get back an array named Example (please pick a better name!)
// composed of zero, one, or many items (again! please pick a better name)
@Query(filter: #Predicate<items> { item in
item.subCategory == "examples"
}, sort: \items.title) private var Example: [items] // <- Here! You have an array now.
Great. Now express what you want to do with the items in that array
. By the way, your vars should be lowercase. You've named yours Example
, which might make a reviewer think this is a Struct
or a Class
. This also applies to the Struct
you've named items
. Struct
names should be capitalized, and singular. An item
Struct
describes ONE item.
What do you want to do with the data in the array?
You did not provide a definition of your item
structure. We're left to guess its contents and what your goals are. So I am bailing on your example and will provide something more sensible (to me).
Turn several element properties into one string
Assumption: After SwiftData
performs a query and returns a number of elements, you want to turn the item.name from the results into a singular array?
// Take your big problem and break it into smaller solvable problems.
// This computed var extracts all the items' names into a single array of Strings
private var allNamesFromSwiftData: [String] {
return Example.map{ $0.name }
}
Here's some code to illustrate this in Playgrounds. Hope(?!) you are using Playgrounds?
// Run this in Playgrounds
// Step 1: Create a struct to hold results.
// This describes ONE TV show.
struct TVShow {
var name: String
var genre: String
// This is a collection of several TVShows. Use as sample data.
static var sampleShows: [TVShow] = [
TVShow(name: "Lost in Space", genre: "SciFi"),
TVShow(name: "Star Trek", genre: "SciFi"),
TVShow(name: "Deep Space 9", genre: "SciFi"),
TVShow(name: "Mandalorian", genre: "Documentary")
]
}
// Step 2: Get an array all TV Shows
var allShows = TVShow.sampleShows // Copy the static collection to a var
// Note: allShows is an array of TVShow objects.
// Step 3: Get an array of JUST the show names
// Note: showNames is an arry of String.
// It is NOT an array of TVShows
var showNames = allShows.map { $0.name }
// map turns all the objects in an array into another type of object.
// Here we're turning TVShow objects into Strings (ie, the TV show name)
// Step 4: Prove to yourself you have an array of just show names
showNames.forEach { print($0) } // Show the contents of the showNames array
// Step 5: Create a new string.
// First join the array elements with a separator "***"
// Then replace spaces with underscores.
let oneString = showNames.joined(separator: "***").replacingOccurrences(of: " ", with: "_")
// Step 6: Validate
print(oneString ) // <-- Print the final string
// prints: Lost_in_Space***Star_Trek***Deep_Space_9***Mandalorian
PS: Please edit your initial post and move ALL YOUR CODE into the code markup. Some of your code is OUTSIDE the markup.
Keep Coding