How to find an item in an object of array - arrays

I have a list of IDs. Also I have an object that has arrays of datas like the below structure.
[
foods(
foodId: 345,
category: 10,
tools: [10],
name: "food name 1"
),
foods(
foodId: 191,
category: 4,
tools: [2],
name: "food name 2"
),
]
In my list I have list [345, 191]
I want to have a mechanism to access the information of the object when I provide a foodId.
I made it work with one inner and one outer loop. But I was wondering if there is an easier way to do it:
ForEach(foodDetails, id: \.self){ item in
ForEach(self.foods.datas){ ex in
if(ex.foodId == item){
Text(ex.name)
}
}
Any idea how to make it work?
Thanks in advance

you can do simply by getting first element where id match
let result = foodDetails.first(where: {$0.foodId == id})
if let food = result {
print(food.name ?? "") //if name is optional
print(food.foodId)
print(food.category)
}
result you got is that foods? optional struct which have this id

Related

Swift: Group duplicate array elements into new array

I have an Order object as follows:
struct Order {
let id: Int
let item: String
let price: Int
}
These are grouped in an, however sometimes there are duplicate IDs and I need these to be grouped into their own array of Order duplicate objects. So essentially at the moment I have [Order] and I need to convert this into [[Order]] where all duplicates will be grouped together, and where there are no duplicates they will simply be on their own in an array.
So for example, imagine I have the following array of orders:
[Order(id: 123, item: "Test item1", price: 1)
Order(id: 345, item: "Test item2", price: 1)
Order(id: 678, item: "Test item3", price: 1)
Order(id: 123, item: "Test item1", price: 1)]
This needs to be converted to:
[[Order(id: 123, item: "Test item1", price: 1), Order(id: 123, item: "Test item1", price: 1)],
[Order(id: 345, item: "Test item2", price: 1)],
[Order(id: 678, item: "Test item3", price: 1)]]
I have been playing around with a dictionary and have so far come up with the following:
let dictionary = Dictionary(grouping: orders, by: { (element: Order) in
return element.id
})
This returns the following type:
[Int : [Order]]
Which is close, but I don't really want them in a dictionary like this. I just need to be able to get an [[Order]] array that I can loop through for use in my UI.
All you have to do is to use .values on the dictionary you have created and you have your array,
let values = Dictionary(grouping: orders, by: \.id).values
This somewhat should do the trick, not the best solution but should be enough to get it working.
var orders = [[Order]]()
for order in orders {
if let index = orders.firstIndex(where: { $0.id == order.id }) {
// We have this order id already let's append another duplicate
orders[index].append(order)
} else {
// We don't have this order id, create a new array
orders.append([order])
}
}

Filter array by matching id properties

I feel like this has to be answered some where, but I have been searching for a few days with no luck. I have an example below. I have an array of users and I need to filter them down to the ones that have a matching ID property, I know the code below doesn't compile.. would be very grateful for any help with this.
struct User {
var id: Int
var name: String
}
let userArray = [
User(id: 1, name: "A"),
User(id: 2, name: "B"),
User(id: 1, name: "C"),
User(id: 3, name: "D"),
]
let newArray = userArray.filter({ $0.id == $1.id })
// This is what i want to achieve
// newArray = [User(id: 1, name: "A"), User(id: 1, name: "C")]
In the actual project, the id is dynamically returned. So I just need to be able to check for what is matching, without knowing what the id will actually be.
Your approach won't work as filter only takes one dynamic parameter and only processes one item at a time. Therefore it can't match two separate array entries.
You example also doesn't specify how you want to handle the situation where you have multiples of different User.id. This answer assumes you want to be able to separate them into separate arrays.
Dictionary has a handy initialiser that will do the bulk of the work for you and group on a defined property. Grouping on id will give you a dictionary where the key is the id and the values an array of matching User records. You can then filter the dictionary to get a dictionary where there are multiple users for any id.
let multiples = Dictionary(grouping: userArray, by: \.id).filter{$0.value.count > 1}
Using your data you will end up with a dictionary of:
[1: [User(id: 1, name: "A"), User(id: 1, name: "C")] ]
Your condition in filter does not compare to a given id value. Below is one added called, which I call matchingId:
struct User {
var id: Int
var name: String
}
let userArray = [
User(id: 1, name: "A"),
User(id: 2, name: "B"),
User(id: 1, name: "C"),
User(id: 3, name: "D"),
]
let matchingId = 1 // or: let matchingId = someFunctionCallReturningAnId()
let result = userArray.filter { $0.id == matchingId }
print(result)

Fetch only values from neo4j database

I am trying to fetch some data from my neo4j database and show in a list for auto suggestion in reactjs application. I have following codes to fetch the data.
let result = null;
try {
result = await session.run(
'MATCH (n:Person) RETURN properties(n)',
)} finally {
await session.close()
}
await driver.close()
Here the Person nodes have different properties, i.e. all the Person nodes do not have same properties. some have editor name, others have author name. What i want to do is fetching only values without keys and assigning them in an array. here
'MATCH (n:Person) RETURN properties(n)'
returns
{
"myName": "myname 1",
"hisName": "myname 2"
}
{
"herName": "myname 3",
"theirName": "myname 4"
}
And 'MATCH (n:Person) RETURN keys(n)' returns
["myName"]
["hisName"]
["herName"]
["theirName"]
But i want to fetch only values [myname 1, myname 2, myname 3, myname 4]
Could you please tell me how to fetch only values ?
Also how to keep those values in an array ?
This is how to get all values for the key myName in Person class.
Check if the node has this property using EXISTS
Put the values in an array using "COLLECT".
MATCH (n:Person)
WHERE EXISTS(n.myName)
RETURN collect(distinct n.myName)
Sample result:
["Zhen", "Praveena", "Michael", "Arya", "Karin", "Adam", "John", "mary", "jack", "david", "tom"]
This will work.
MATCH(n:Person)
RETURN apoc.coll.flatten(COLLECT(EXTRACT(key IN keys(n) | n[key])))
p.s. Sorry, EXTRACT() has been deprecated. Below is better.
MATCH(n:Shima)
RETURN apoc.coll.flatten(COLLECT([key IN keys(n) | n[key]]))

Filter array of types, based on array of properties in type

I am working in an Angular 9 project (Typescript).
I have an array of strings. I also have an array of a custom type.
How do I filter the array of custom type to only include those whose property match one of the strings in the string array.
Here's some code to help explain:
//I declare a custom type
export interface CustomType {
id: string;
name: string;
}
//I declare my arrays
customTypesArr: CustomType[] = [
{id: "000", name: "name 1"},
{id: "001", name: "name 2"},
{id: "002", name: "name 3"}
];
customTypesNamesArr: string[] = ["name 3", "name 1"];
Now I want to create an array from customTypesArr that only includes items whose name property is the same as any string in customTypesNamesArr.
The end result would be:
myNewCustomTypesArr: CustomType[] = [
{id: "000", name: "name 1"},
{id: "002", name: "name 3"}
];
I'm thinking it would be something like this, but I can't quite hammer it out:
customTypesArr.filter(item =>
customTypesNamesArr.forEach(name => {
if (name == item.name) {
return item;
}
})
);
I'm really not sure on if I should be using forEach() in this scenario...
Any help would be appreciated. Thank you.
var filtered = customTypesArr.filter(function(item)
{
return customTypesNamesArr.indexOf(item.name) !== -1;
});
You could use the includes method of arrays to make this pretty simple.
customTypesArr.filter(item => customTypesNamesArr.includes(item.name));
Basically, just do a filter where you you check to see if each item's name is includeed the array of names that are allowed.

AngularJS filter by id returns multiple entrys

i had an array like this:
arr = [
{ID: 502, Description: 'aaa', code: 1122},
{ID: 2, Description: 'bbb', code: 2211},
{ID: 700, Description: 'ccc', code: 2222}
];
when i try to filter the ID I get all occurences of the specific number:
$(filter)('filter')( arr, { ID: 2 } )[0]
returns entry one ID: 502 but it should return the entry with ID: 2
Where is my fault?
According to the docs when used with an object it will match the element if it contains the value.
A pattern object can be used to filter specific properties on objects contained by array. For example {name:"M", phone:"1"} predicate will return an array of items which have property name containing "M" and property phone containing "1".
There is a second option comparator passing true will cause it to perform a strict equality meaning it should only return exact matches.
$filter('filter')( arr, { ID: 2 }, true);
Fiddle: https://jsfiddle.net/enxbpjg0/
You could use a function instead of the object. So...
$filter('filter')(arr, function(value) {
return value.ID === 2;
});

Resources