I'm struggling to get the string values from a Map<string, List<string>> object. The object contains this information:
{"thisKeyName": [Array]}
The [Array] contains something like this:
["Contact 1", "Contact 2", "Contact 3"]
I'm able to access the [Array] values of the object like this:
let contactCards = currentUser.contacts; // <- this is the Map object
const ids = [];
contactCards.forEach(folder => {
folder.forEach(contact => {
ids.push(contacts);
});
});
However, I want to access the "ThisKeyName" value to put it on another array. How can I achieve this?
Related
I’m building search functionality. I have an array of User objects and each User has a dictionary of tags. I’m trying to return users with searched tags.
My user class is:
class User: NSObject {
var name: String?
var tags = Dictionary<String, String>()
}
An example of the tags is:
tags: {
“entry1” : “test1”,
“entry2” : “test2”,
“entry3” : “test3”
}
I’ve been trying variances of:
let predicate = NSPredicate(format: “tags contains[c] %#", “test1”);
let filteredArray = self.usersArray!.filter { predicate.evaluate(with: $0) }; print(“users = ,\(filteredArray)");
It’s throwing “this class is not key value coding-compliant for the key tags.’ I'm not sure how to search inside the User object.
Update:
I've change the dictionary to an array and
filter { $0.tags.contains(searchTerm) } works for exact search match, as suggested.
.filter( {$0.tags.reduce(false, {$1.contains(searchTerm)} )} ) does not work for a partial match however, which is what i'm looking for.
Here is what is printed:
Search term: ale
Result: []
Tags array inside each object:
["Alex", "Will", ""]
["Bob", "Dan", ""]
["First", "Second", "Third"]
["Testing 1", "Testing 2", ""]
Your implementation of tags seems cumbersome. Here is a simpler one.
class User {
var name: String
var tags: [String]
}
Now let's say you have an array of users in users.
var users: [User]
// Store users in the array
Now, this is how you check which user contains a particular tag.
let tag = "yourTag"
users.filter( { $0.tags.contains(tag) } )
However, if you are adamant that you need the tags in a dictionary, then you could do it like this,
users.filter( {$0.tags.values.contains(tag)} )
If you want to check if the tag is part of any of the tags in a particular user, you could do it like this,
let filteredUsers = users.filter( {$0.tags.reduce(false, {$1.contains(tag)} )} )
P.S - we don't use ; in Swift.
It's good practice to make your models conform to Codeable:
struct User: Codable {
var userId: UUID
var name: String = ""
var referenceTags: [String: String] = [:]
}
// Create some users:
let Bob = User(userId: UUID(), name: "Bob", referenceTags: ["tag1": "no", "tag2": "yes"])
let Steve = User(userId: UUID(), name: "Steve", referenceTags: ["tag2": "no", "tag3": "no"])
Create an array of users to filter.
let users:[User] = [Bob, Steve]
Get a search predicate or string from your Search bar or other.
let searchPredicate = "yes"
Filter and iterate over tags for the required value.
let results = users.filter { (user) -> Bool in
for (key, _) in user.referenceTags.enumerated() {
if (user.referenceTags[key] == searchPredicate) {
return true
}
}
}
"name": [
{
"name": "test1"
},
{
"name": "test2"
},
{
"name": "test3"
},
{
"name": "test1"
},
]
I have the above created by nodejs. During array push, I would like to remove duplicated arrays from the list or only push the name array if the individual array does not exist.
I have tried below codes but it changes the array.
var new = [];
for (var i =0;i<name.length;i++){
new['name'] = name[i].name;
}
The easiest way is probably with Array.prototype.reduce. Something along these lines, given your data structure:
obj.name = Object.values(obj.name.reduce((accumulator, current) => {
if (!accumulator[current.name]) {
accumulator[current.name] = current
}
return accumulator
}, {}));
The reduce creates an object that has keys off the item name, which makes sure that you only have unique names. Then I use Object.values() to turn it back into a regular array of objects like in your data sample.
the solution can be using temp Set;
const tmpSet = new Set();
someObj.name.filter((o)=>{
const has = tmpSet.has(o.name);
tmp.add(o.name);
return has;
});
the filter function iterating over someObj.name field and filter it in place if you return "true". So you check if it exists in a tmp Set & add current value to Set to keep track of duplicates.
PS: new is a reserved word in js;
This should do it
const names = ['John', 'Paul', 'George', 'Ringo', 'John'];
let unique = [...new Set(names)];
console.log(unique); // 'John', 'Paul', 'George', 'Ringo'
https://wsvincent.com/javascript-remove-duplicates-array/
I have the following code where I design the format of a JSON-array dynamically from variables ==>
var Title = '"text_title"'
var Topic2 = '"text_topic2"'
var jsonData = [ ];
createWantedJSON("title", data[i].topic, jsonData)
function createWantedJSON(title, Topic2, arr) {
arr.push({
"Topic": title,
[Topic2] : {
"Topic3": [{
"Subitem1": "Text1",
"Subitem2": "Text2",
"Subitem3": "Text3"
}]
}
}
This goes fine for the key and value which are not nested. But I don't know how to make it dynamic for the content of Topic3. I tried making a variable with the following content =>
'"Subitem1": "Text1", "Subitem2": "Text2", "Subitem3": "Text3"' but then of course it sees the content as one string and not as elements of the nested Topic3 array. I guess this isn't that hard but I can't seem to fix it.
So I have the following JSON, which I am using together with ObjectMapper and Realm.
{
"result": [
{
"id": 20,
"types": [
"now"
],
"url": "/nl/whereto/ezrhgerigerg",
"categories": [
{
"id": 39,
"name": "Food "
},
{
"id": 21,
"name": "Varia"
}
]
},
My problem is getting the data from "types", which for some items in the array says "now" or "later", and is empty for other items (hence, no types item is given).
I tried to do the following in my mapping:
class Publication: Object, Mappable {
dynamic var id:Int = 0
var typez = List<getType>()
dynamic var url:String?
required convenience init?(_ map: Map) {
self.init()
}
override static func primaryKey() -> String? {
return "id"
}
func mapping(map: Map) {
id <- map["id"]
typez <- map["types"]
url <- map["url"]
}
}
class getType: Object, Mappable {
dynamic var text: String = ""
required convenience init?(_ map: Map) {
self.init()
}
func mapping(map: Map) {
text <- map[""]
}
}
When I check the Realm database, you can see that typez, an array of [getType] was made, but it's empty for all items (even the ones where types is "now"). The other two items (id and url) are filled in in the database.
What am I doing wrong that it won't save to the database?
Because Realm cannot detect assigning List properties since List property is not Objective-C type. So List properties should be declared as let, and should not be nil. You should use append/remove.../insert...method to modifying theList`.
So your code
typez <- map["types"]
doesn't work, since you assign values to the typez property directly.
The workaround is like the following:
func mapping(map: Map) {
...
var typez: [String]? = nil
typez <- map["types"]
typez?.forEach { t in
let obj = getType()
obj.text = t
self.typez.append(obj)
}
...
First, store the mapped value to the local variable (it is string array). Then convert the string array to objects. Then append the objects to the List property.
I am new to using Realm. Is there an easy way to save an array to a realm object? I am receiving my data from a JSON REST call:
class SomeClass: RLMObject {
dynamic var id = 0
dynamic var name = ""
dynamic var array: NSArray
func checkForUpdates() {
// Download JSON data here... The results have an array inside of them.
SomeClass.createOrUpdateInDefaultRealmWithObject(SomeNSDictionary)
}
override class func primaryKey() -> String! {
return "id"
}
}
Is it possible to save the array in the JSON results in Realm?
Thanks.
Realm has a special RLMArray type, which allows storing a collection of RLMObject's tied to a parent RLMObject. For example, say you had the following JSON:
{
"name": "John Doe",
"aliases": [
{"alias": "John"},
{"alias": "JD"}
]
}
You could model this with the following classes:
class Alias: RLMObject {
dynamic var alias = ""
}
class Person: RLMObject {
dynamic var name = ""
dynamic var aliases = RLMArray(objectClassName: "Alias")
}
So you could simply create a Person object with the following API call:
Person.createInRealm(realm, withObject: jsonObject)
You can learn more about how RLMArrays work from Realm's reference documentation: http://realm.io/docs/cocoa/0.80.0/api/Classes/RLMArray.html