I have two lists as below. How can I combine the elements in the list within themselves?
var cars = [
{"id" : 1, "title" : "BMW"},
{"id" : 2, "title" : "Toyota"}
];
var attr = [{"hp" : 250}, {"hp" : 130}];
How can I get it to print out this way?
[{"id": 1, "title": BMW", "hp": 250}, {"id": 2, "title": "Toyota", "hp": 130}]
I assume both list have same number of items and each item needs to be merged to the item at the same index on the other list.
In that case, you can either use a for loop to iterate through those lists and merge or you can just use forEach method.
cars.asMap().forEach((index, value) => () {
return value.addAll(attr[index]);
}());
print(cars);
Output:
[{id: 1, title: BMW, hp: 250}, {id: 2, title: Toyota, hp: 130}]
var cars = [
{"id" : 1, "title" : "BMW"},
{"id" : 2, "title" : "Toyota"}
];
var attr = [{"hp" : 250}, {"hp" : 130}];
var newList = [];
for (int i=0;i<cars.length;i++){
Map newCar = {
"id":cars[i]["id"],
"title":cars[i]["title"],
"hp":attr[i]["hp"],
};
newList.add(newCar);
}
print(newList);
For me, that's the simplest solution that comes to my mind
If you want to do it without using a third list then you must follow this. This is simple logic and can be used for larger lists as well.
List<Map> cars = [
{"id" : 1, "title" : "BMW"},
{"id" : 2, "title" : "Toyota"}
];
List<Map> attr = [{"hp" : 250}, {"hp" : 130}];
for(int i = 0; i<cars.length;i++){
for(int j = 0; j<attr.length;j++){
if(i==j){
cars[i].addAll(attr[j]);
}
}
}
print(cars);
Related
I have a List of Objects in the file list.dart:
final itemList = [
ItemData(uuid: 'one', score: '30', title: 'Title One', description: 'mock description'),
ItemData(uuid: 'two', score: '10', title: 'Title Two', description: 'mock description'),
ItemData(uuid: 'three', score: '20', title: 'Title Three', description: 'mock description'),
];
I am calling back UUID: 'one' to another widget in the file edit.dart
return GestureDetector(
onTap: (){
currentItem = item.uuid; //currentItem declared in file edit.dart
DisplayItem(); //callback function to edit.dart
},
child: Card(
My plan is to use the callback function to get the elements with the corresponding uuid. My problem is I can't figure out how to find the index of the object with the element equal to a given uuid. I've tried nesting indexOf() but get exponentially confused.
So if I understand correctly, you have a list of items and you want to find the index of the first item that fulfils a condition (in this case the condition is that the items UUID value is equal to some value)
In order to do something like that, you can use the indexWhere method:
var targetUuid = 'one';
int itemIndex = itemList.indexWhere((item) => item.uuid == targetUuid);
print(itemList[itemIndex]);
you can find the index of object as:
void main() {
final List<Map<String, dynamic>> _people = [
{"id": "c1", "name": "John Doe", "age": 40},
{"id": "c2", "name": "Kindacode.com", "age": 3},
{"id": "c3", "name": "Pipi", "age": 1},
{"id": "c4", "name": "Jane Doe", "age": 99},
];
// Find index of the person whose id = c3
final index1 = _people.indexWhere((element) => element["id"] == "c3");
if (index1 != -1) {
print("Index $index1: ${_people[index1]}");
}
// Find the last index where age > 80
final index2 = _people.lastIndexWhere((element) => element["age"] > 80);
if (index2 != -1) {
print("Index $index2: ${_people[index2]}");
}
}
Output:
Index 2: {id: c3, name: Pipi, age: 1}
Index 3: {id: c4, name: Jane Doe, age: 99}
Swift 3:
I've two arrays, one is an array of the dictionary(json) and another is of indexes (Int value) of index Path (Collection type Index with element row & section). With the help of index rows of the second array, I need to remove, elements from the first array.
var arrayString = [ // Array with Json elements
{ "name" : "A" },
{ "name" : "B" },
{ "name" : "C" },
{ "name" : "D" },
{ "name" : "E" },
{ "name" : "F" },
{ "name" : "G" },
{ "name" : "H" }
]
Now Second array (to be removed from the first array)
var arrayIndex = [ 2, 3, 5 ] // Array with
How can I do this?
I want resulting array like
var arrayString = [
{ "name" : "A" },
{ "name" : "D" },
{ "name" : "F" },
{ "name" : "G" },
{ "name" : "H" }
]
Your array arrayIndex is look like Array of Int not array of IndexPath.
arrayIndex.sorted(by: >).forEach { if $0 < self.arrayString.count { self.arrayString.remove(at: $0) } }
If arrayIndex is Array of IndexPath then use row property to remove the object from array.
arrayIndex.sorted(by: { $0.row > $1.row }).forEach { if $0.row < self.arrayString.count { self.arrayString.remove(at: $0.row) } }
Here's a functional approach using enumerated, filter, contains, and map to create the array:
var arrayString = [
[ "name" : "A" ],
[ "name" : "B" ],
[ "name" : "C" ],
[ "name" : "D" ],
[ "name" : "E" ],
[ "name" : "F" ],
[ "name" : "G" ],
[ "name" : "H" ]
]
let arrayIndex = [2, 3, 5]
arrayString = arrayString.enumerated()
.filter { !arrayIndex.contains($0.0 + 1) }
.map { $0.1 }
print(arrayString)
[["name": "A"], ["name": "D"], ["name": "F"], ["name": "G"], ["name": "H"]]
Explanation:
.enumerated() takes the original array and creates an array of tuple pairs containing the index of each item paired with the item: (index, item)
filter selects those items from the resulting array that return true from the passed (trailing) closure. In this case, an item is selected if its index is not in arrayIndex
map is used to pull just the item from the resulting array of tuples
the index was increased by 1 because your example seemed to indicate that your arrayIndex started at 1 and not 0
I have nested collection and I add "Data" then foreach "Data" I add its own "Tags". I found unwind for "Data" with foreach for "Tags".
I wanna add person which I import its info from outside of collection manually.
I execute below Cypher query by statements:
I have imitated from:
Cypher Import Statement
AND
Cypher Unwind
I checked my json via enter link description here And it is validated.
{ "statements": [ { "statement": " WITH { "categories": [ {"dataid" : "11" , "dataname" : "data1" , "datalanguage" : "en" , "datatype" : "type1" ,"content" : "content1" , "tags" : [{"myid" : "11" , "tagid" : 10 , "tagname" : "tag1" }] } , {"dataid" : "22" , "dataname" : "data2" , "datalanguage" : "en" , "datatype" : "type2" ,"content" : "content2" , "tags" : [{"myid" : "22" , "tagid" : 20 , "tagname" : "tag2" }] } ] } AS document UNWIND document.categories AS category MERGE (dt:Data {name: category.dataname}) ON CREATE SET dt.id = category.dataid , dt.type = category.datatype , dt.language = category.datalanguage , dt.content = category.datacontent MERGE (p:Person { name : 'Mahsa' , lastname : 'Mahsa' } ) ON CREATE SET p.id =1 MERGE (p)-[r:owner]->(dt) FOREACH (mytag IN category.tags | MERGE (t:Tag {name: mytag.tagname}) ON CREATE SET t.id = mytag.tagid MERGE (dt)-[r2:tagged { Freq : 12 ]->(t) )" } ] }
But it returns as result: (I checked many times for "Unexpected character" but I could not find )
{"results":[],"errors":[{"code":"**Neo.ClientError.Request.InvalidFormat**","message":"**Unable to deserialize request: Unexpected character ('c' (code 99)): was expecting comma to separate OBJECT entries**\n at [Source: HttpInputOverHTTP#132e16b; line: 1, column: 48]"}]}
I made my nested collection as:
string dataCollection2 = "{ \"categories\": [ {\"dataid\" : \"11\" , \"dataname\" : \"data1\" , \"datalanguage\" : \"en\" , \"datatype\" : \"type1\" ," +
"\"content\" : \"content1\" , \"tags\" : [{\"myid\" : \"11\" , \"tagid\" : 10 , \"tagname\" : \"tag1\" }] }" +
" , {\"dataid\" : \"22\" , \"dataname\" : \"data2\" , \"datalanguage\" : \"en\" , \"datatype\" : \"type2\" ," +
"\"content\" : \"content2\" , \"tags\" : [{\"myid\" : \"22\" , \"tagid\" : 20 , \"tagname\" : \"tag2\" }] } ] }";
var obj1 = JValue.Parse(#"'" + dataCollection2 + "'");
I imported my json to http://jsonlint,com and I got it is validated:
{
"categories": [
{
"dataid": 11,
"dataname": "data1",
"datalanguage": "en",
"datatype": "type1",
"content": "content1",
"tags": [
{
"myid": 11,
"tagid": 10,
"tagname": "tag1"
}
]
},
{
"dataid": 22,
"dataname": "data2",
"datalanguage": "en",
"datatype": "type2",
"content": "content2",
"tags": [
{
"myid": 22,
"tagid": 20,
"tagname": "tag2"
}
]
}
]}
The fundamental problem with the string you are passing to the REST API is that you are not passing a legal Cypher query. Cypher property "maps", which look a bit like JSON, are NOT JSON.
In your case, the important difference is that property names must NOT be delimited by double-quotes. Only string property values can be delimited by double-quotes.
So, categories, dataId, dataName, etc., must not be surrounded by double-quotes.
You also have a typo near the end of the query. [r2:tagged { Freq : 12 ] should be [r2:tagged { Freq : 12} ].
For Adding nested collection to neo4j:
Firstly: For having right input to neo4j as parameter I must remove "{
"categories": [ ] }" from the first and the end of json.
Secondly: I should put this json as parameter to statement
Thirdly: I have to use two "UNWIND and WITH" (instead of using foreach) for separating each row from collection either for parent or for child.
"Foreach" DOES similar to "UNWIND and WITH".
My final collection and query are:
Collection:
{"id" : 1, "name" : "Data1", "language" : "en", "tags": {"id" : 11, "name": "tag 11" } } , {"id" : 2, "name": "Data2" , "tags": [ {"id" : 33, "name": "tag 33"} , {"id" : 44, "name": "tag44"} ] }
Query:
{ "statements": [ { "statement": " UNWIND { datas } AS data MERGE (p:Person { name : 'God' , lastname : 'God' } ) ON CREATE SET p.id =2 MERGE (d:Data {name: data.name}) ON CREATE SET d.id = data.id , d.language = data.language MERGE (p)-[r:owner]->(d) WITH d, data.tags AS mytags UNWIND mytags AS mytag MERGE (t:Tag {name: mytag.name}) ON CREATE SET t.id = mytag.id MERGE (d)-[r2:tagged { Freq : 12 } ]->(t) " , "parameters": { "datas" : [{"id" : 1, "name" : "Data1", "language" : "en", "tags": {"id" : 11, "name": "tag 11" } } , {"id" : 2, "name": "Data2" , "tags": [ {"id" : 33, "name": "tag 33"} , {"id" : 44, "name": "tag44"} ] }] } } ] }
Consider the following example of mongo collection:
{"_id" : ObjectId("4f304818884672067f000001"), "hash" : {"call_id" : "1234"}, "something" : "AAA"}
{"_id" : ObjectId("4f304818884672067f000002"), "hash" : {"call_id" : "1234"}, "something" : "BBB"}
{"_id" : ObjectId("4f304818884672067f000003"), "hash" : {"call_id" : "1234"}, "something" : "CCC"}
{"_id" : ObjectId("4f304818884672067f000004"), "hash" : {"call_id" : "5555"}, "something" : "DDD"}
{"_id" : ObjectId("4f304818884672067f000005"), "hash" : {"call_id" : "5555"}, "something" : "CCC"}
I would like to query this collection and get only the first entry for each "call_id", in other words i'm trying to get unique results based on "call_id".
I tried to use .distinct method:
#result = Myobject.all.distinct('hash.call_id')
but the resulting array will contain only the unique call_id fields:
["1234", "5555"]
and I need all the other fields too.
Is it possible to make a query like this one?:
#result = Myobject.where('hash.call_id' => Myobject.all.distinct('hash.call_id'))
Thanks
You cannot simply return the document(or subset) by using the distinct. As per the documentation it only returns the distinct array of values based on the given key. But you can achieve this by using map-reduce
var _map = function () {
emit(this.hash.call_id, {doc:this});
}
var _reduce = function (key, values) {
var ret = {doc:[]};
var doc = {};
values.forEach(function (value) {
if (!doc[value.doc.hash.call_id]) {
ret.doc.push(value.doc);
doc[value.doc.hash.call_id] = true; //make the doc seen, so it will be picked only once
}
});
return ret;
}
The above code is self explanatory, on map function i am grouping it by key hash.call_id and returning the whole doc so it can be processed by reduce funcition.
On reduce function, just loop through the grouped result set and pick only one item from the grouped set (among the multiple duplicate key values - distinct simulation).
Finally create some test data
> db.disTest.insert({hash:{call_id:"1234"},something:"AAA"})
> db.disTest.insert({hash:{call_id:"1234"},something:"BBB"})
> db.disTest.insert({hash:{call_id:"1234"},something:"CCC"})
> db.disTest.insert({hash:{call_id:"5555"},something:"DDD"})
> db.disTest.insert({hash:{call_id:"5555"},something:"EEE"})
> db.disTest.find()
{ "_id" : ObjectId("4f30a27c4d203c27d8f4c584"), "hash" : { "call_id" : "1234" }, "something" : "AAA" }
{ "_id" : ObjectId("4f30a2844d203c27d8f4c585"), "hash" : { "call_id" : "1234" }, "something" : "BBB" }
{ "_id" : ObjectId("4f30a2894d203c27d8f4c586"), "hash" : { "call_id" : "1234" }, "something" : "CCC" }
{ "_id" : ObjectId("4f30a2944d203c27d8f4c587"), "hash" : { "call_id" : "5555" }, "something" : "DDD" }
{ "_id" : ObjectId("4f30a2994d203c27d8f4c588"), "hash" : { "call_id" : "5555" }, "something" : "EEE" }
and running this map reduce
> db.disTest.mapReduce(_map,_reduce, {out: { inline : 1}})
{
"results" : [
{
"_id" : "1234",
"value" : {
"doc" : [
{
"_id" : ObjectId("4f30a27c4d203c27d8f4c584"),
"hash" : {
"call_id" : "1234"
},
"something" : "AAA"
}
]
}
},
{
"_id" : "5555",
"value" : {
"doc" : [
{
"_id" : ObjectId("4f30a2944d203c27d8f4c587"),
"hash" : {
"call_id" : "5555"
},
"something" : "DDD"
}
]
}
}
],
"timeMillis" : 2,
"counts" : {
"input" : 5,
"emit" : 5,
"reduce" : 2,
"output" : 2
},
"ok" : 1,
}
You get the first document of the distinct set. You can do the same in mongoid by first stringify the map/reduce functions and call mapreduce like this
MyObject.collection.mapreduce(_map,_reduce,{:out => {:inline => 1},:raw=>true })
Hope it helps
I have user document collection like this:
User {
id:"001"
name:"John",
age:30,
friends:["userId1","userId2","userId3"....]
}
A user has many friends, I have the following query in SQL:
select * from user where in (select friends from user where id=?) order by age
I would like to have something similar in MongoDB.
To have everything with just one query using the $lookup feature of the aggregation framework, try this :
db.User.aggregate(
[
// First step is to extract the "friends" field to work with the values
{
$unwind: "$friends"
},
// Lookup all the linked friends from the User collection
{
$lookup:
{
from: "User",
localField: "friends",
foreignField: "_id",
as: "friendsData"
}
},
// Sort the results by age
{
$sort: { 'friendsData.age': 1 }
},
// Get the results into a single array
{
$unwind: "$friendsData"
},
// Group the friends by user id
{
$group:
{
_id: "$_id",
friends: { $push: "$friends" },
friendsData: { $push: "$friendsData" }
}
}
]
)
Let's say the content of your User collection is the following:
{
"_id" : ObjectId("573b09e6322304d5e7c6256e"),
"name" : "John",
"age" : 30,
"friends" : [
"userId1",
"userId2",
"userId3"
]
}
{ "_id" : "userId1", "name" : "Derek", "age" : 34 }
{ "_id" : "userId2", "name" : "Homer", "age" : 44 }
{ "_id" : "userId3", "name" : "Bobby", "age" : 12 }
The result of the query will be:
{
"_id" : ObjectId("573b09e6322304d5e7c6256e"),
"friends" : [
"userId3",
"userId1",
"userId2"
],
"friendsData" : [
{
"_id" : "userId3",
"name" : "Bobby",
"age" : 12
},
{
"_id" : "userId1",
"name" : "Derek",
"age" : 34
},
{
"_id" : "userId2",
"name" : "Homer",
"age" : 44
}
]
}
Edit: this answer only applies to versions of MongoDb prior to v3.2.
You can't do what you want in just one query. You would have to first retrieve the list of friend user ids, then pass those ids to the second query to retrieve the documents and sort them by age.
var user = db.user.findOne({"id" : "001"}, {"friends": 1})
db.user.find( {"id" : {$in : user.friends }}).sort("age" : 1);
https://docs.mongodb.org/manual/reference/operator/aggregation/lookup/
This is the doc for join query in mongodb , this is new feature from version 3.2.
So this will be helpful.
You can use in Moongoose JS .populate() and { populate : { path : 'field' } }.
Example:
Models:
mongoose.model('users', new Schema({
name:String,
status: true,
friends: [{type: Schema.Types.ObjectId, ref:'users'}],
posts: [{type: Schema.Types.ObjectId, ref:'posts'}],
}));
mongoose.model('posts', new Schema({
description: String,
comments: [{type: Schema.Types.ObjectId, ref:'comments'}],
}));
mongoose.model('comments', new Schema({
comment:String,
status: true
}));
If you want to see your friends' posts, you can use this.
Users.find(). //Collection 1
populate({path:'friends', //Collection 2
populate:{path:'posts' //Collection 3
}})
.exec();
If you want to see your friends' posts and also bring all the comments, you can use this and too, you can indentify the collection if this not find and the query is wrong.
Users.find(). //Collection 1
populate({path:'friends', //Collection 2
populate:{path:'posts', //Collection 3
populate:{path:'commets, model:Collection'//Collection 4 and more
}}})
.exec();
And to finish, if you want get only some fields of some Collection, you can use the propiertie select Example:
Users.find().
populate({path:'friends', select:'name status friends'
populate:{path:'comments'
}})
.exec();
MongoDB doesn't have joins, but in your case you can do:
db.coll.find({friends: userId}).sort({age: -1})
one kind of join a query in mongoDB, is ask at one collection for id that match , put ids in a list (idlist) , and do find using on other (or same) collection with $in : idlist
u = db.friends.find({"friends": ? }).toArray()
idlist= []
u.forEach(function(myDoc) { idlist.push(myDoc.id ); } )
db.friends.find({"id": {$in : idlist} } )
Only populate array friends.
User.findOne({ _id: "userId"})
.populate('friends')
.exec((err, user) => {
//do something
});
Result is same like this:
{
"_id" : "userId",
"name" : "John",
"age" : 30,
"friends" : [
{ "_id" : "userId1", "name" : "Derek", "age" : 34 }
{ "_id" : "userId2", "name" : "Homer", "age" : 44 }
{ "_id" : "userId3", "name" : "Bobby", "age" : 12 }
]
}
Same this: Mongoose - using Populate on an array of ObjectId
You can use playOrm to do what you want in one Query(with S-SQL Scalable SQL).
var p = db.sample1.find().limit(2) ,
h = [];
for (var i = 0; i < p.length(); i++)
{
h.push(p[i]['name']);
}
db.sample2.find( { 'doc_name': { $in : h } } );
it works for me.
You can do it in one go using mongo-join-query. Here is how it would look like:
const joinQuery = require("mongo-join-query");
joinQuery(
mongoose.models.User,
{
find: {},
populate: ["friends"],
sort: { age: 1 },
},
(err, res) => (err ? console.log("Error:", err) : console.log("Success:", res.results))
);
The result will have your users ordered by age and all of the friends objects embedded.
How does it work?
Behind the scenes mongo-join-query will use your Mongoose schema to determine which models to join and will create an aggregation pipeline that will perform the join and the query.