Kotlin functional programming keep reference of previous object in List - kotlin

I have a list of Person objects which are related to each other with spouse relation in the order of which they appear in the list.
enum class Gender {
MAN, WOMAN
}
data class Person(val name: String, val age: Int, val gender: Gender)
In the list, each Person with Gender MAN is the spouse of the following Person with WOMAN Gender (and vice versa) and each entry in the list is followed by alternating genders with MAN gender be the first.
The list should ideally be like [MAN, WOMAN, MAN, WOMAN, MAN, WOMAN] (obviously it will be a list of Person objects for simplicity I am putting a list of Gender here) but it could also be like [WOMAN, MAN, WOMAN, MAN, WOMAN, MAN]. In the latter case, the first appearing WOMAN is the spouse of the last appearing MAN.
How this second case could be handled in kotlin by using functional programming.
My current approach involves checking if the first Person has a gender women then i remove the first and last objects in the list and then add them in the end but this is not fully a functional programming solution.
Anyone can guide me about that?
Thanks

What do you mean by fully functional approach?
Similar to what you mentioned, you can fix the order by a simple statement like this:
val correctList = if(list.first().gender == MAN) list else list.drop(1) + list.first()

If you want a more general approach, you can do something like this:
// separate the people into a list of gender=MAN and a list of everyone else
// the result is a Pair, so I'm destructuring that into two variables
val (men, women) = people.partition { it.gender == MAN }
// use zip to take a person from each list and combine them into a list of pairs
men.zip(women)
// use flatMap to turn each pair into a list of two people
// just using map would create a list of lists, flatMap flattens that into
// a single list of people, alternating gender=MAN, gender=WOMAN
.flatMap { it.toList() }
This way it doesn't matter how your original list is ordered, it can start with any element and you can have the different types completely mixed up - BABBAABA will still come out as ABABABAB. So it's a general way to combine mixed data streams - partition separates them into groups, and zip lets you take an element from each group and do something with them.
Here I'm just letting zip create Pairs, and then flatMap turns those back into an ordered list (if that's what you want). You could also do a forEach on each pair instead (say if you wanted to set a value on each Person to link them to each other), or zip can take a transform function too.
Also zip terminates when one of the lists runs out (e.g for AAA and BB you'll get two pairs) so this works for generating complete pairs of elements - if you also needed to handle elements without a "partner" you'd need to do a bit more work

Related

Xcode - Objective C- How to make a dictionary of persons?

I can't get my head around my objective C code. I want to make a dictionary with persons that I save in the app. The dictionary is in first empty and then we need to add it from the textfields I created (see image)textfieldWelkom
For every person that is added, we have to show it in a list (see image) lijstTabblad in the tableviewcontroller. (The list has to be the whole name of the person)
I don't get the idea of how to making a dictionary with multiple persons with every person his own ELEMENTS. And how that I can get the elements again out of de dictionary for making the list etc..
(not like the 1 example but multiple values with that person)
I would be sow thankfull if you could help me!
Greetings,
Kevin
You needs to first create single person dictionary dictionary keys
are like name sirname age and put values for respected keys
add this dictionary in one array or another dictionary(array/dictionary must be mutable array)

Cypher-Neo4j Node Single Property change to Array

Following is a Node we having in DB
P:Person { name:"xxx", skill:"Java" }
and after awhile, we would like to change the Skill to skill array, is it possible?
P:Person { name:"xxx", skill:["Java", "Javascript"] }
Which Cypher query should I use?
If you have a single skill value in skill, then just do
MATCH (p:Person)
WHERE HAS (p.skill)
SET p.skill=[p.skill]
If there are multiple values you need to convert to an array such as P:Person { name:"xxx", skill:"Java","JavaScript" } then this should work:
MATCH (p:P)
SET p.skill= split(p.skill,",")
In fact, I think your real problem here is not how to get an array property in a node, but how to store it. Your data model is wrong in my opinion, storign data as array in neo4j is not common, since you have relations to store multiple skills (in your example).
How to create your data model
With your question, I can already see that you have one User, and one User can have 1..n skills.
I guess that one day (maybe tomorrow) you will need to know which users are able to use Java, C++, PHP, and every othre skills.
So, Here you can already see that every skill should have its own node.
What is the correct model in this case?
I think that, still with only what you said in question, you should have something like this:
(:Person{name:"Foo"})-[:KNOWS]->(:Skill{name:"Bar"})
using such a data model, you can get every Skill known by a Person using this query:
MATCH (:Person{name:"Foo"})-[:KNOWS]->(skill:Skill)
RETURN skill //or skill.name if you just want the name
and you can also get every Person who knows a Skill using this:
MATCH (:Skill{name:"Bar"})<-[:KNOWS]-(person)
RETURN person //Or person.name if you just want the name
Keep in mind
Storing array values in properties should be the last option when you are using neo4j.
If a property can be found in multiple nodes, having the same value, you can create a node to store it, then you will be able to link it the other nodes using relations, and finding every node having the property X = Y will be easier.

[] or () in REST Urls

Has anyone used either [] or () in your REST API urls?
hypothetical examples:
/cars?[colors]:red,[engineType]:13
/cars?(colors):red,(engineType):13
says give me all cars with color red and a certain engine type. Colors is a sub property of the car resource.
Has anyone seen any issues using these to be aware of or is it pretty common to use?
Here's another example. Give me all the cities but only the cities where its people drink coffee
/cities?filter=(people[drinks[type]:6])
or I could even allow more sets as to perform ANDs like this
/cities?filter=(people[drinks[type]:6]),(another layer of filtering)&paging=(offset:10, limit:2)
essentially in the second, the comma itself is an implicit AND for the query because () denotes a filtering criteria so we have one filtering criteria, comma, second filtering criteria so this could easily be wired up to SQL via () and () if you think about it when parsing the url values out of the request and passing it down to a query in the backend.
this is an idea I have.
() - denotes one filter level, adding multiple () are multiple filters
[] - denotes a sub property of a resource
so the above allows the caller to say give me a list of cities but only those whos people like to drink coffee (type 6).
There isn't really an official specification of REST, but this is very unusual. The normal way to do this is to urlencode your parameters in key=value form. Almost all libraries are going to help you do that. You'd have to hand-parse this custom format you've invented (and you need to figure out any escaping issues; what if , or [ can be part of the string? It's unclear what the brackets are getting you in any case.
A more usual way to approach this would be:
/cars?color=red&engineType=13
There are 2 frequent patterns I met so far:
/cars/?colors=red&engineType=13
/cars/colors:red/engineType:13/
Using [] or () in URIs is not common. I don't think you'll have any issues by using them if that's what you desire. Just don't use {} if you want to use URI templates too.

Remove substring before a specific char (NSString)

Basically I am getting a users city throughout Facebook Connect. The result is always in this format:
Sydney, Australia
But since there will be many users, the city and country can vary. Here is the format:
First the city with a comma, then a space and the country.
I only want to however retrieve the country name. Is it possible for me to locate the comma in string, then remove everything behind it. Then I can replaceOccurancesOfString:" " to remove the space.
I have seen other questions on this but they are in different languages. I am asking for Objective-C
Thanks!
one easy way to do it is to use - (NSArray *)componentsSeparatedByString:(NSString *)separator to make an array out of it, and then pick the second object of the array.

Do you use singular or plural in names of arrays, maps, sets, etc.?

I have a quick question that is not particular technical, but I sometimes wonder what's better ...
Do you use singular or plural in names of arrays, maps, sets, etc.? Example:
Singular
1 std::map<string,double> age;
2 age["diego maradonna"] = 49;
Plural
1 std::map<string,double> ages;
2 ages["diego maradonna"] = 49;
In the plural version, the second line isn't nice (because you're looking up the age, not the ages of Maradonna). In the singular version, the first line sounds kind of wrong (because the map contains many ages).
Singular for instances, plural for collections.
For maps, I will typically even go a step further and name them in terms of both their keys and values (ex. agesByPersonNames). This is especially helpful if you have a map of maps.
Plurals. I use the same kind of names for SQL tables. The case of:
ages["diego maradonna"] = 49;
should be read as "in the collection of ages, find me the one that belongs to maradonna and change it to 49"
I would use nameToAgeMap["diego maradonna"], so it's obvious what you put in (a name) and get out (an age), it reads nicely in assignments: nameToAgeMap["diego maradonna"] = 49; which could be read as "put 49 into the name-to-age map for Diego Maradonna".