Duplicate map is being added to list - dart

void main() {
Map firstMap = { "id": 1, "value": [{"key": "A"}, {"key": "B"}]};
List<Map> newList = [];
List valueList = firstMap["value"];
for(int y=0; y<valueList.length; y++) {
Map newMap = firstMap;
newMap["value"] = [{"key": valueList[y]["key"]}];
newList.add(newMap);
}
print(newList);
}
My expectation for newList is to look like:
[{id: 1, value: [{key: A}]}, {id: 1, value: [{key: B}]}]
but the actual value of newList is
[{id: 1, value: [{key: B}]}, {id: 1, value: [{key: B}]}]
I am not sure what to try here.
valueList[y]["key"] seems to have the correct value in each iteration.
The code above has been shared as a link here to dart pad.
How would I achieve the same? Also what is going on with my code, which is leading to such a result.
Open with Dart pad

Error that you are doing is as already mentioned in the comment, reassignment to different variable does not make a copy of data:
Map a = {"a": 1}
Map b = a; // b is just one more reference to same object
b["a"] = 2;
print(a); // -> {"a": 2}
Transformations from one shape to another can be conveniently done with map()
https://dartpad.dartlang.org/8283e91c2c201ddb65ef073e76995f1d
void main() {
Map firstMap = { "id": 1, "value": [{"key": "A"}, {"key": "B"}]};
List valueList = firstMap["value"];
List<Map> newList = valueList.map((valueItem) => {
"id": firstMap["id"],
"value": [valueItem]
}).toList();
print(newList);
}

Related

How to convert list into string with quotes Dart

I have a list and want it as a string with quotes List myList = [1,2,3]
require O/P as List myList = ["1","2","3"]
i think this works as you need!
void main(List<String> arguments) {
List myList = [1, 2, 3];
List myNewList = [];
myList.forEach((item) {
myNewList.add("\'$item\'");
});
}
so the print of myList would be [1, 2, 3]
and the print of myNewList would be ['1', '2', '3'].
by the way...
The order of the quotation signs is arbitrary and the meaning of
"\'$item\'"
is the same as
'\"$item\"'
The difference is that your output from
"\'$item\'"
would be
['1', '2', '3']
and the output of
'\"$item\"'
would be
["1", "2", "3"].
I think you want something like this:
List<String> myList = <String>["'1'","'2'","'3'"];
Or you can use it this way:
List<String> myList = <String>['\'1'\','\'2'\','\'3\''];

Dart - How to check if my list has same values for departmentId?

For example I have list as:
List<Map<String, dynamic>> employees = [
{"name": 'Kris', 'departmentId': 18, CityId: 1},
{"name": 'Ana', 'departmentId': 18, CityId: 2},
{"name": 'Monty', 'departmentId': 18, CityId: 3},
{"name": 'John', 'departmentId': 18, CityId: 4},
];
If you have a List, and you want to make sure that all items in the list have a certain property, you can use List.every. For example:
bool isEven(int n) => n % 2 == 0;
[1, 2, 3, 4].every(isEven) // false, some values are not even
[2, 4, 6, 8].every(isEven) // true, every value is even
In your case, you can check that every value of departmentId has the same value as the first (if you don't know that id ahead of time).
bool allHaveSameDepartment(List<Map<String, dynamic>> employees) {
bool sameIdAsFirst(Map<String, dynamic> employee) => employee['departmentId'] == employees[0]['departmentId'];
return employees.every(sameIdAsFirst);
}
Note that in this case, an empty list will return true (https://en.wikipedia.org/wiki/Vacuous_truth). You may wish to override this behaviour by checking employees.isEmpty at the start and maybe throwing an error or returning false.
I got the solution by using toSet().
Solution: employees.map((value) => value.departmentId).toSet().length.

Boost documents in search results which are matched to array

I have this relatively complex search query that's already being built and working with perfect sorting.
But I think here searching is slow just because of script so all I want to remove script and write query accordingly.
current code :-
"sort": [
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "double pscore = 0;for(id in params.boost_ids){if(params._source.midoffice_master_id == id){pscore = -999999999;}}return pscore;",
"params": {
"boost_ids": [
3,
4,
5
]
}
}
}
}]
Above code explaination:-
For example, if a match query would give a result like:
[{m_id: 1, name: A}, {m_id: 2, name: B}, {m_id: 3, name: C}, {m_id: 4, name: D}, ...]
So I want to boost document with m_id array [3, 4, 5] which would then transform the result into:
[{m_id: 3, name: C}, {m_id: 4, name: D}, {m_id: 1, name: A}, {m_id: 2, name: B}, ...]
You can make use of the below query using Function Score Query(for boosting) and Terms Query (used to query array of values)
Note that the logic I've mentioned is in the should clause of the bool query.
POST <your_index_name>/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {} //just a sample must clause to retrieve all docs
}
],
"should": [
{
"function_score": { <---- Function Score Query
"query": {
"terms": { <---- Terms Query
"m_id": [
3,4,5
]
}
},
"boost": 100 <---- Boosting value
}
}
]
}
}
}
So basically, you can remove the sort logic completely and add the above function query in your should clause, which would give you the results in the order you are looking for.
Note that you'd have to find a way to add the logic correctly in case if you have much complex query, and if you are struggling with anything, do let me know. I'd be happy to help!!
Hope this helps!

How to sort map value?

I have this map:
var temp= {
'A' : 3,
'B' : 1,
'C' : 2
};
How to sort the values of the map (descending). I know, I can use temp.values.toList()..sort().
But I want to sort in context of the keys like this:
var temp= {
'B' : 1,
'C' : 2
'A' : 3,
};
This example uses a custom compare function which makes sort() sort the keys by value. Then the keys and values are inserted into a LinkedHashMap because this kind of map guarantees to preserve the order.
Basically the same as https://stackoverflow.com/a/29629447/217408 but customized to your use case.
import 'dart:collection';
void main() {
var temp= {
'A' : 3,
'B' : 1,
'C' : 2
};
var sortedKeys = temp.keys.toList(growable:false)
..sort((k1, k2) => temp[k1].compareTo(temp[k2]));
LinkedHashMap sortedMap = new LinkedHashMap
.fromIterable(sortedKeys, key: (k) => k, value: (k) => temp[k]);
print(sortedMap);
}
Try it on DartPad
The SplayTreeMap has a named constructor which accepts map and a comparator which is used to sort given map while building new map. Since SplayTreeMap is a descendant of Map you can easily substitute it.
import 'dart:collection';
void main() {
var unsorted = {'A': 3, 'B': 1, 'C': 2};
final sorted = SplayTreeMap.from(
unsorted, (key1, key2) => unsorted[key1].compareTo(unsorted[key2]));
print(sorted);
}
final Map<String, ClassCategory> category;
...
Map<String, ClassCategory> sorted = SplayTreeMap.from(category,
(key1, key2) => category[key1]!.title.compareTo(category[key2]!.title));
for (var item in sorted.entries) {
...
}

Can Neo4j return additional property maps

I am using the cypher rest api manually for this.
I would like to return the data in a way that is easy to parse.
Here's an example of some data with the same sort of relationships I'm dealing with:
(me:Person:Normal),
(dad:Person:Geezer),
(brother:Person:Punk),
(niece:Person:Tolerable),
(daughter:Person:Awesome),
(candy:Rule),
(tv:Rule),
(dad)-[:HAS_CHILD {Num:1}]->(brother),
(dad)-[:HAS_CHILD {Num:2}]->(me),
(me)-[:HAS_CHILD {Num:1}]->(daughter),
(brother)-[:HAS_CHILD {Num:1}]->(niece),
(me)-[:ALLOWS]->(candy),
(me)-[:ALLOWS]->(tv)
I want to get all of the HAS_CHILD relationships and if any of those child nodes have :ALLOWS relationships I want the ids of those too.
so if I were to do something like...
START n=node({idofdad}) MATCH n-[r?:HAS_CHILD]->h-[?:ALLOWS]->allowed
WITH n, r, h, collect(ID(allowed)) as allowedIds
WITH n, r,
CASE
WHEN h IS NOT NULL THEN [ID(h), LABELS(h), r.Num?, allowedIds]
ELSE NULL
END as has
RETURN
LABELS(n) as labels,
ID(n) as id,
n as node,
COLLECT(has) as children;
The :HAS_CHILD may not exist, so I have to do this wierd case thing.
The data that comes back is 'ok' but the JSON mapper that I have (Newtonsoft) doesn't make it easy to map an array to an object (meaning I know that array index[0] is ID of the (children) collections.
The results of the above look like this:
{
"columns": ["labels", "id", "node", "children"],
"data": [
["Person", "Geezer"],
6,
{},
[
[7, ["Person", "Normal"], 2, [2, 1]],
[5, ["Person", "Punk"], 1, []]
]
]
}
Since this is more/less a document and it'd be easier to map the 'children' column I'd like to get something that looks like this:
{
"columns": ["labels", "id", "node", "children"],
"data": [
["Person", "Geezer"],
6,
{},
[
[
"id": 7,
"labels": ["Person", "Normal"],
"ChildNumber": 2,
"AllowedIds": [2, 1]
},
{
"id": 5,
"labels": ["Person", "Punk"],
"ChildNumber": 1,
"AllowedIds": []
}
]
]
}
I would expect the query to look something like:
START n=node({idofdad}) MATCH n-[r?:HAS_CHILD]->h-[?:ALLOWS]->allowed
WITH n, r, h, collect(ID(allowed)) as allowedIds
WITH n, r,
CASE
WHEN h IS NOT NULL THEN
{ id: ID(h), labels: LABELS(h), ChildNumber: r.Num?, AllowedIds: allowedIds }
ELSE NULL
END as has
RETURN
LABELS(n) as labels,
ID(n) as id,
n as node,
COLLECT(has) as children;
Is this even remotely possible?

Resources