How to flatten a nested array in Dart? - arrays

How do I flatten a nested array?
[
{
"page": 1,
"items": [
{
"addresses": [
"hello1",
"hello2"
]
}
]
},
{
"page": 2,
"items": [
3,
{
"addresses": [
"hello3",
"hello4"
]
}
]
},
{
"page": 3,
"items": [
3,
4
]
}
];
Desired output ist:
["hello1", "hello2", "hello3", "hello4"]
import 'dart:convert';
main() {
const jsonString =
'[{"page":1, "items": [{"addresses": ["hello1","hello2"]}]}, {"page":2, "items": [3, {"addresses": ["hello3","hello4"]}]}, {"page":3, "items": [3, 4]}]';
final items = jsonDecode(jsonString) as List;
final x = items.expand((p) => p["items"]).expand((p) => p["addresses"]);
print(x);
}

Ok, so you have a list of maps that look like this:
{
page: int,
items: List<{
addresses: List<String>
}>
except sometimes the items are just numbers, you want to get all addresses on a single list, here is how I would do it:
List<String> result = [];
p.forEach((obj) {
final objMap = obj as Map<String, dynamic>
objMap['items'].forEach((item) {
if (item is Map<String, dynamic>) {
result.addAll(item['addresses'] as List<String>);
}
});
});
A bit clunky, I know, but I think it will do the trick

Related

How to add field to nested array that looks at another field in the same array item MongoDb

for example i have
{
...
myObjects = [ {nmbr: 1}, {nmbr:2}]
}
now I want:
{
...
myObjects = [ {nmbr: 1, id: 1}, {nmbr:2, id :2}]
}
using:
db.collection.aggregate([
{
"$addFields": {
"myObjects.id": "$myObjects.nmbr"
}
}
])
has this result
{
...
myObjects = [ {nmbr: 1, id_:[1,2]}, {nmbr:2, id:[1,2]}]
}
which is not what I expected, any solution?
$unwind: Deconstructs myObjects array field from the source documents to output a document for each element.
$addFields: Create id property with value myObject.nmbr in myObject field.
$group: Group by $id (ObjectId) to combine into myObjects array (reverse $unwind).
db.collection.aggregate([
{
"$unwind": "$myObjects"
},
{
"$addFields": {
"myObjects.id": "$myObjects.nmbr"
}
},
{
$group: {
_id: "$id",
"myObjects": {
$push: "$myObjects"
}
}
}
])
Output
[
{
"_id": null,
"myObjects": [
{
"id": 1,
"nmbr": 1
},
{
"id": 2,
"nmbr": 2
}
]
}
]
Sample Mongo Playground

Converting a json response in nodejs

I'm trying to convert a json response code, but i keep getting a back a string array instead.
The header fields are depending on the table I query, so I cannot hardcode these.
I get a json response like:
{
"records": [
[
1,
"page one",
300
],
[
2,
"page 2",
500
]
],
"header: [
"page_id",
"page_name",
"total"
]
}
But i would like to convert this to
{
[
{
"page_id": 1,
"page_name": "page one",
"total": 300
},
{
"page_id": 2,
"page_name": "page 2",
"total": 500
}
]
}
I tried to create an Array and converting this to json but it still returns a string array, instead of a json array
let array = new Array;
records.forEach((record) => {
const parts = [];
let i = 0;
header.forEach((title) => {
const part = title + ': ' + record[i];
parts.push(part);
i++;
});
array.push(JSON.parse(JSON.stringify(parts)));
});
console.log(array) // Shows a string array?
I would expect
{
[
{
"page_id": 1,
"page_name": "page one",
"total": 300
},
{
"page_id": 2,
"page_name": "page 2",
"total": 500
}
]
}
But actual
[
[ 'page_id: 1', 'page_name: page 1', 'total: 300'],
[ 'page_id: 2', 'page_name: page 2', 'total: 500']
]
The issue with the way you are doing it, is you are creating an array and pushing the values onto it, where what you want to do is create the array and push objects onto it that contain your values...
This can be done with a small amount of code using map (documentation here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
results.records.map((arr)=> ({
page_id: arr[0],
page_name: arr[1],
total: arr[2]
});
You can also deconstruct it like so
results.records.map(([page_id, page_name, total])=> ({
page_id,
page_name,
total,
});
/*jshint esversion: 6 */
let records = {
"records": [
[
1,
"page one",
300
],
[
2,
"page 2",
500
]
],
"header": [
"page_id",
"page_name",
"total"
]
};
let arr1 = records.header.map(data => data + ":");
let finalarray = new Array(10);
var keys = arr1;
var values = records.records;
finalarray = [];
values.forEach((data,index) =>{
var objJSON = new Object({});
for (i = 0; i < keys.length; i++) {
objJSON[keys[i]] = data[i];
}
finalarray.push(objJSON);
});
console.log(finalarray);
I have stored your given data in records object and then mapped the headers with colon ":" and in second loop I have joined both arrays in json object.
Output is now:
[ { 'page_id:': 1, 'page_name:': 'page one', 'total:': 300 },
{ 'page_id:': 2, 'page_name:': 'page 2', 'total:': 500 } ]

In Mongoose, query fields based on array

I am trying to query documents from a mongodb collection, based on array of input query parameters sent from URL.
Sample Database Data
[
{
"drawings": {
"circle": [],
"square": [
{
"id": "828",
"name": "square"
}
],
"cube": []
},
{
"drawings": {
"circle": [
{
"id": "827",
"name": "circle"
}
],
"square": [],
"cube": []
},
{
"drawings": {
"circle": [],
"square": [],
"cube": [
{
"id": "829",
"name": "cube"
}
]
}
]
Input Query Parameter:
query = ["square","cube"];
Expected Output:
[
{
"drawings": {
"circle": [],
"square": [
{
"id": "828",
"name": "square"
}
],
"cube": []
},
{
"drawings": {
"circle": [],
"square": [],
"cube": [
{
"id": "829",
"name": "cube"
}
]
}
]
Best suited Mongoose Query:
Schema.find({
$or:[
{'drawings.square':{$elemMatch:{ name:'square'}}},
{'drawings.cube':{$elemMatch:{ name:'cube'}}}
]
});
Tried Below method. But, it is not correct.
let draw = ["square","cube"];
let draw_query =[];
for (let a=0; a<draw.length;a++){
draw_query.push("{\"drawings."+ draw[a] +"\':{$elemMatch:{ name:\"" + draw[a] + "\"}}}");
}
It creates array with single quoted strings. It cannot be used.
[ '{"drawings.square":{$elemMatch:{ name:"square"}}}',
'{"drawings.cube":{$elemMatch:{ name:"cube"}}}' ]
How to generate this mongoose query dynamically? or is there any better mongoose query to achieve the expected result.
You can query it directly using dot notation so the query should look like below:
db.collection.find({
$or: [
{
"drawings.square.name": "square"
},
{
"drawings.circle.name": "circle"
}
]
})
You can build it in JS using .map(), try:
var query = ["square","cube"];
var orQuery = { $or: query.map(x => ({ [x + ".name"]: x }) ) }

Loop through Dictionary in Swift

I have a dictionary which I want to append some items.
**This is my dictionary which I want to achieve: **
let parameters: [String: Any] = [
{
"ResultsList": [{
"UserId": "b806e283-066f-4081-aafe-1fe216a57c35",
"FriendUserId": "7a2ec150-cdb3-4600-84f8-2dab970bfa0c",
"TransferDate": "2017-11-23",
"UserAnswers": [{
"AnswerId": "b7562603-614d-11e7-a7e0-484d7ee0cd26",
"LastAnsweredDate": "2017-11-23",
"QuestionId": "0b60f35e-5d80-11e7-a7e0-484d7ee0cd26"
},
{
"AnswerId": "b7562603-614d-11e7-a7e0-484d7ee0cd26",
"LastAnsweredDate": "2017-11-23",
"QuestionId": "0b60f35e-5d80-11e7-a7e0-484d7ee0cd26"
}
]
}]
}
]
And this is my current dictionary which I want to make the loop and add the items.
let parameters: [String: Any] = [
{
ResultsList: [
{
UserId: “b806e283-066f-4081-aafe-1fe216a57c35”
FriendUserId: “7a2ec150-cdb3-4600-84f8-2dab970bfa0c”
TransferDate: “2017-11-23”
UserAnswers: [
{
AnswerId: “b7562603-614d-11e7-a7e0-484d7ee0cd26"
LastAnsweredDate: “2017-11-23”
QuestionId : “0b60f35e-5d80-11e7-a7e0-484d7ee0cd26"
}
]
}
]
}
]
I have 3 arrays which I want to loop through and append to the dictionary
var AnswerId = [ “b7562603-614d-11e7-a7e0-484d7ee0cd26", “aasdaas-614d-11e7-a7e0-484d7ee0cd26", “b756asd03-614d-11e7-a7e0-484d7ee0cd26"]
var LastAnsweredDate = [“2017-11-23”, “2017-11-23”, “2017-11-22”]
var QuestionId = [“0b60f35e-5d80-11e7-a7e0-484d7ee0cd26",“asdasd-5d80-11e7-a7e0-484d7ee0cd26",“asdasd-5d80-11e7-a7e0-484d7ee0cd26"]
Can someone please help to achieve this result?

Mongoose-MongoDb : doc.pull inconsistent when multiple pull

node v7.7.1
mongodb: 2.2.33,
mongoose: 4.13.7
Hello all,
i'm having this unexpected behaviour when trying to update a document with multiple pull request based on matching criterias. here is what i mean
my document schma looks like this
{
"_id": "5a1c0c37d1c8b6323860dfd0",
"ID": "1511781786844",
"main": {
"_id": "5a3c37bfc065e86a5c593967",
"plan": [
{
"field1": 1,
"field2": 1,
"_id": "5a3c30dfa479bb4b5887e56e",
"child": []
},
{
"field1": 1,
"field2": 2,
"_id": "5a3c30e1a479bb4b5887e5c",
"child": []
},
{
"field1": 1,
"field2": 3,
"_id": "5a3c37bfc065e86a5c593968",
"child": []
},
{
"field1": 1,
"field2": 4,
"_id": "5a3c37bfc065e86a5c593655",
"child": []
},
{
"field1": 1,
"field2": 5,
"_id": "5a3c30dfa479bb4b5887e56f",
"child": []
},
{
"field1": 1,
"field2": 6,
"_id": "5a3c30e1a479bb4b6887e545",
"child": []
},
{
"field1": 1,
"field2": 7,
"_id": "5a3c37bfc065e86a5c5939658",
"child": []
},
{
"field1": 2,
"field2": 2,
"_id": "5a3c37bfc065e86a5c593963",
"child": []
},
]
},
...
....
}
and this is my code to update the document:
Schema.findOne({ID: data.ID})
.then(function(doc) {
var array = doc.main.plan;
for (i = 0; i < array.length; i++) {
if ( array[i].field1=== 1 )) {
var id = array[i]._id;
console.log('pulling');
doc.pull( { _id: id });
}
}
doc.save().then(function(doc) {
console.log('saving');
// console.log(doc);
if (doc && doc.docID) {
return { success: true };
} else {
return { success: false, error: 'unknownError'}
}
})
}
now the issue is let's say my array has 7 objects that matches the test (array[i].theField === parseInt(updFields.theField)), when i run this and check the logs i see that it will basically pull half of the objects and do a save.
so i would get
pulling
pulling
pulling
pulling
save.
and then i have to run the code for the remaining 3 objects in the array and get
pulling
pulling
saving
so i have to run it a third time to completely clear the array.
need help get this working
thank you
So i created a little workaround by doing a recursive function to pull all with only one click using lodash functions. not pretty but it does the job.
const delObjArray = (doc, cond) => {
const checkField = cond.field;
const checkVal = cond.value;
_.forEach(doc, (value) => {
if (value && value[checkField] === checkVal) {
doc.pull({ _id: value._id });
}
});
const isFound = _.some(doc, { [checkField]: checkVal });
if (isFound) {
delObjArray(doc, cond);
} else {
return true;
}
return true;
};

Resources