TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Creating a single String from SwiftData query (.map?, .reduce?, .joined?)

Forums > SwiftUI

Trying to create a single string that i can then use a sharelink for in my pracitce app. Having trouble figuring out which method to use. I've tried .reduce, joined, and .map. Everything I've searched on the web is 6 or 7 years old and appears deprecated. Here is the code from the view i'm looking at. I bring the query in then i try to create a button that stores the string in a state variable. The model has an object with one attriubte called title and another called description, and a subcategory attribute as well.

import SwiftUI import SwiftData

struct PracticeView: View {

@Query(filter: #Predicate<items> { item in
    item.subCategory == "examples"
}, sort: \items.title) private var Example: [items]

@State var changingString: String = ""

@State var newArray: [items]

var body: some View {
    Button(action: {
        changingString =  Core.reduce("") {
            $0 + $1.title
            print(changingString)
            return(changingString)
        }
    }, label: {
        Text("Button")
    })

}

}

2      

@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

2      

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.