Populating fields from 1 object into another through (for ... in ...) loop - javascript

The issue I'm having is as follows: I'm attempting to populate a Javascript object (called Table) with content from another object (called Messages)
I'm trying to do this by matching 2 keys in the Table object with 2 keys from the Messages object. The keys I'm trying to match can be described as 'row' and 'cell'.
If the message 'row' and 'cell' match, I push the message into the cell.
Information
- Rows are unique keys at the top level of the object and are called 'labs'.
- Cells are unique keys in Rows, but a Cell key might have a duplicate in another row. They are called 'steps'.
My thoughts were that to uniquely identify a cell, it would be possible to compare the Row + Cell key of the Table cell I want to populate with the Row + Cell key of the message. If they match, populate the Table cell.
The object I'm trying to populate looks as following (before population):
{
"570f5233c8640c8819dae6a2": {
"570f5215c8640c8819dae6a0": {
"_id": "570f5215c8640c8819dae6a0",
"time": 2,
"type": "Type 1",
"order": 0,
"messages": []
},
"570f927196fa91ab0a1d8793": {
"_id": "570f927196fa91ab0a1d8793",
"time": 0,
"type": "Type 2",
"order": 1,
"messages": []
}
},
"570f52caecbdcb2c1a7031f1": {
"570f5215c8640c8819dae6a0": {
"_id": "570f5215c8640c8819dae6a0",
"time": 2,
"type": "Type 1",
"order": 0,
"messages": []
},
"570f927196fa91ab0a1d8793": {
"_id": "570f927196fa91ab0a1d8793",
"time": 0,
"type": "Type 2",
"order": 1,
"messages": []
}
}
}
The code I'm using to populate the object above as follows (I'm populating the messages field):
for (let msgKey in messages) {
if (messages.hasOwnProperty(msgKey)) {
for (let tableRowKey in table) {
if (table.hasOwnProperty(tableRowKey)) {
for (let cellRowKey in table[tableRowKey]) {
if (table[tableRowKey].hasOwnProperty(cellRowKey)) {
let msgRow = messages[msgKey].lab.toString();
let msgStep = messages[msgKey].step.toString();
if (tableRowKey === msgRow && cellRowKey === msgStep) {
table[tableRowKey][cellRowKey].messages.push(messages[msgKey]);
}
}
}
}
}
}
}
The output from the code looks as follows (after population):
{
"570f5233c8640c8819dae6a2": {
"570f5215c8640c8819dae6a0": {
"_id": "570f5215c8640c8819dae6a0",
"time": 2,
"type": "Type 1",
"order": 0,
"messages": [
{
"step": "570f5215c8640c8819dae6a0",
"time": 2,
"timeActual": 0.00010335648148148148,
"timeDifference": null,
"isComplete": true,
"lab": "570f5233c8640c8819dae6a2"
}
]
},
"570f927196fa91ab0a1d8793": {
"_id": "570f927196fa91ab0a1d8793",
"time": 0,
"type": "Type 2",
"order": 1,
"messages": [
{
"step": "570f927196fa91ab0a1d8793",
"time": 0,
"timeActual": 0.00007015046296296297,
"timeDifference": null,
"isComplete": true,
"lab": "570f52caecbdcb2c1a7031f1"
}
]
}
},
"570f52caecbdcb2c1a7031f1": {
"570f5215c8640c8819dae6a0": {
"_id": "570f5215c8640c8819dae6a0",
"time": 2,
"type": "Type 1",
"order": 0,
"messages": [
{
"step": "570f5215c8640c8819dae6a0",
"time": 2,
"timeActual": 0.00010335648148148148,
"timeDifference": null,
"isComplete": true,
"lab": "570f5233c8640c8819dae6a2"
}
]
},
"570f927196fa91ab0a1d8793": {
"_id": "570f927196fa91ab0a1d8793",
"time": 0,
"type": "Type 2",
"order": 1,
"messages": [
{
"step": "570f927196fa91ab0a1d8793",
"time": 0,
"timeActual": 0.00007015046296296297,
"timeDifference": null,
"isComplete": true,
"lab": "570f52caecbdcb2c1a7031f1"
}
]
}
}
}
If it was matching correctly, the message would be populated in an object when the message "lab" key and the message "step" key matched the parent keys. So a correct object would look as follows:
"570f5233c8640c8819dae6a2": {
"570f5215c8640c8819dae6a0": {
"_id": "570f5215c8640c8819dae6a0",
"time": 2,
"type": "Type 1",
"order": 0,
"messages": [
{
"step": "570f5215c8640c8819dae6a0",
"time": 2,
"timeActual": 0.00010335648148148148,
"timeDifference": null,
"isComplete": true,
"lab": "570f5233c8640c8819dae6a2"
}
]
}
However, the code is in fact populating messages in fields where the parent keys do not match, as you can see from the after population code included above.
What exactly is wrong here, to me the code looks correct, am I missing something about matching Javascript keys?

Related

Creating new json by taking url addresses from existing json and split it up Javascript

I have a json file.
[
{
"line": 1,
"elements": [
{
"start_timestamp": "2022-10-17T20:07:41.706Z",
"steps": [
{
"result": {
"duration": 12216552000,
"status": "passed"
},
"line": 5,
"name": "m0e",
"match": {
"location": "seleniumgluecode.book.user_is_on_homepagee()"
},
"keyword": "Given "
},
{
"result": {
"duration": 2074982200,
"status": "passed"
},
"line": 6,
"name": "m1e1",
"match": {
"location": "seleniumgluecode.book.user_enters_Usernamee()"
},
"keyword": "When "
}
],
"tags": [
{
"name": "#Smokee"
}
]
},
{
"start_timestamp": "2022-10-17T20:08:12.284Z",
"steps": [
{
"result": {
"duration": 12090584100,
"status": "passed"
},
"line": 12,
"name": "m0e2",
"match": {
"location": "seleniumgluecode.book2.user_is_on_homepageee()"
},
"keyword": "Given "
}
],
"tags": [
{
"name": "#Smokee"
}
]
}
],
"name": "Login Featuree",
"description": " Verify if user is able to Login in to the sitee",
"id": "login-featuree",
"keyword": "Feature",
"uri": "file:src/test/java/features/tribe/squad1/kitab.feature",
"tags": []
},
{
"line": 1,
"elements": [
{
"start_timestamp": "2022-10-17T20:08:34.480Z",
"steps": [
{
"result": {
"duration": 11366098500,
"status": "passed"
},
"line": 5,
"name": "m0e",
"match": {
"location": "seleniumgluecode.book.user_is_on_homepagee()"
},
"keyword": "Given "
}
],
"tags": [
{
"name": "#Smokee"
}
]
}
],
"name": "Login Featureefghfgh",
"description": " Verify if user is able to Login in to the sitee",
"id": "login-featureefghfgh",
"keyword": "Feature",
"uri": "file:src/test/java/features/tribe1/squad2/kitab2.feature",
"tags": []
},
{
"line": 19,
"elements": [
{
"start_timestamp": "2022-10-17T20:09:40.836Z",
"steps": [
{
"result": {
"duration": 12761711100,
"status": "passed"
},
"line": 23,
"name": "m0e",
"match": {
"location": "seleniumgluecode.book.user_is_on_homepagee()"
},
"keyword": "Given "
}
],
"tags": [
{
"name": "#Smokee"
}
]
}
],
"name": "X Feature",
"description": " Verify if user is able to Login in to the sitee",
"id": "login-featuree",
"keyword": "Feature",
"uri": "file:src/test/java/features/tribe2/test.feature",
"tags": []
}
]
I am getting url addresses in this array
document.addEventListener("DOMContentLoaded", () => {
var i = report.length;
var array = [];
for(x = 0; x < i; x++){
array.push(report[x].uri.split("/"));
}
console.log(array2);
});
This return me :
0:
(7) ['file:src', 'test', 'java', 'features', 'tribe1', 'squad1', 'kitab.feature']
1:
(7) ['file:src', 'test', 'java', 'features', 'tribe1', 'squad2', 'kitab2.feature']
2:
(6) ['file:src', 'test', 'java', 'features', 'tribe2, kitab3.feature']
I don't need file:src, test, java, features. Deleting them in 3 arrays and getting a unique array like this:
0:
(3) ['tribe1', 'squad1', 'kitab.feature']
1:
(3) ['tribe1', 'squad2', 'kitab2.feature']
2:
(2) ['tribe2, kitab3.feature']
Finally, if there are 2 elements before the .feature, I need to create a new array by considering 1 as squad and 2 as tribe. Like this:
Diagram
[tribe1
squad1
elem
1
2
name
url
squad2
elem
1
2
name
url
tribe2
elem
1
2
name
url
]
How can I do that?. Thank you.
You should try destructing the array. An example is shown below:
[a,b,c,d, ...rest] = ['file:src', 'test', 'java', 'features', 'tribe1', 'squad1', 'kitab.feature']
console.log(rest);
You can transform or create a new array based on input array with this simple logic with the help of Array.map() along with String.split() and Array.splice() method.
Live Demo :
const arr = [
{
"line": 1,
"uri": "file:src/test/java/features/tribe/squad1/kitab.feature"
},
{
"line": 1,
"uri": "file:src/test/java/features/tribe1/squad2/kitab2.feature"
},
{
"line": 19,
"uri": "file:src/test/java/features/tribe2/test.feature"
}
];
const res = arr.map(({ uri}) => uri.split('/').splice(4));
console.log(res);

Group by id and get order by total count in mongoose express node js

I have a collection like that:
{
"_id": {
"$oid": "5f54b3333367b91bd09f4485"
},
"products": [
{
"_id": 20,
"name": "Türk Kahvesi",
"price": 8,
"count": 2
},
{
"_id": 22,
"name": "Dibek",
"price": 10,
"count": 2
},
{
"_id": 21,
"name": "Damla Sakızlı T.K.",
"price": 10,
"count": 1
}
],
"deskId": "5f53473611f7490d3c860ccd",
"waiterId": "1",
"deskName": "Ü2",
},
{
"_id": {
"$oid": "5f54af663367b91bd09f4483"
},
"products": [
{
"_id": 20,
"name": "Türk Kahvesi",
"price": 8,
"count": 1
},
{
"_id": 21,
"name": "Damla Sakızlı T.K.",
"price": 10,
"count": 1
},
{
"_id": 22,
"name": "Dibek",
"price": 10,
"count": 1
},
{
"_id": 23,
"name": "Menengiç",
"price": 10,
"count": 1
},
{
"_id": 25,
"name": "Double Espresso",
"price": 15,
"count": 6
}
],
"deskId": "5f53473611f7490d3c860ccd",
"waiterId": "1",
"deskName": "Ü2",
}
And my goal is, getting all data order and group by product._id and show totalPrice(price*count),products.name, _id and totalCount. This is actually to show us a report product by product. If you need any more information, Just ask. Sample result:
{
{
"_id": 20,
"name": "Türk Kahvesi",
"totalCount": 3,
"totalPrice": 24
},
{
"_id": 22,
"name": "Dibek",
"totalCount": 3,
"totalPrice": 30
},
{
"_id": 21,
"name": "Damla Sakızlı T.K.",
"totalCount": 2,
"totalPrice": 20
},
{
"_id": 23,
"name": "Menengiç",
"totalCount": 1,
"totalPrice": 10
},
{
"_id": 25,
"name": "Double Espresso",
"totalCount": 6,
"totalPrice": 90
}
}
We can use aggregate on something. Please help me.
I'm still new to MongoDB, but I think this aggregate pipeline is what you're looking for. That said this is the kind of thing you should research yourself using the documentation, but as long as you understand the thought process you'll learn something so it's all good!
[
{
$unwind: {
path: '$products',
// Here we are seperating each item in the products array of
// the user(I presumed your objects were users, or carts maybe)
// It will now be available to the next stage of the pipeline as
// a singular object for each item in the array,
// see the picture below for how this works practically.
}
},
{
$group: {
// Now we're going to restructure the object to
// center around the id field of the products, and
// at the same time we can add up the total price
// and count of each item.
_id: '$products.id', // This is the selector for the grouping process (in our case it's the id)
item: { $first: '$$ROOT.products' }, // this is me thinking you'll want access to the item in question for each total.
totalCount: { $sum: "$products.count" }, // adds to totalCount EACH $products.count that we have
totalPrice: { $sum: { $multiply: ["$products.price", '$products.count'] } }, // self explanatory
}
}
]
this is what unwind does to your array and object
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
NB I modified/removed some variable names(_id, oid) for practical reasons, you'll have to parse through which ones and this code will most likely not work right away if copy-pasted.

How to remove items from an array of multidimensional arrays

I need some help on how to remove items from a TreeView (it's a Vue.js project), the TreeView is build based on an element like that:
[
{
"id": 1,
"name": "COMERCIALIZAÇÃO",
"idp": "",
"children": [
{
"id": 5,
"name": "Pasta 1",
"idp": 1,
"children": [
{
"id": 6,
"name": "Pasta 1 2",
"idp": 5,
"children": [
{
"id": 7,
"name": "NO.FT.DRC.01.00.001.pdf",
"file": "pdf",
"idp": 6
},
{
"id": 8,
"name": "PR.FT.DRC.01.00.003.pdf",
"file": "pdf",
"idp": 6
}
]
},
{
"id": 9,
"name": "imprimir p luiza.pdf",
"file": "pdf",
"idp": 5
},
{
"id": 66,
"name": "Pasta 1 3",
"idp": 5,
"children": [
{
"id": 77,
"name": "NO.FT.DRC.01.00.001.pdf",
"file": "pdf",
"idp": 66
},
{
"id": 88,
"name": "PR.FT.DRC.01.00.003.pdf",
"file": "pdf",
"idp": 66
}
]
}
]
},
{
"id": 10,
"name": "Backend.docx",
"file": "pdf",
"idp": 1
},
{
"id": 0,
"name": "DT.DC.RPI.03.03.1235_V2.docx",
"file": "pdf",
"idp": 1
}
]
},
{
"id": 2,
"name": "DISTRIBUIÇÃO",
"idp": "",
"children": [
{
"id": 11,
"name": "Pasta 2",
"idp": 2,
"children": [
{
"id": 12,
"name": "pasta 2 1",
"idp": 11,
"children": [
{
"id": 13,
"name": "script.sql",
"file": "pdf",
"idp": 12
}
]
}
]
}
]
},
{
"id": 3,
"name": "GERAÇÃO",
"idp": "",
"children": [
{
"id": 14,
"name": "Pasta 3",
"idp": 3
}
]
},
{
"id": 4,
"name": "SERVIÇOS",
"idp": "",
"children": [
{
"id": 5,
"name": "teste",
"idp": 4
}
]
}
]
I'm not sure, but I think that the best way to describe that element is: array of mutidimensional arrays, right?
I've created a CodePen to show the closest I got when using recursivity, but surely mine isn't the best solution since it doesn't work on every delete. Take a look at my code: https://codepen.io/luizarusso/pen/zYxLOPb?editors=1010
for (let i = 0; i < items.length; i++) {
if (items[i].id == item.id) {
//se achou o cara que vai ser removido, chama a função de remover
return this.removeItem(i);
} else {
if (items[i].children) {
if (items[i].idp == "") {
this.caminho = [];
}
this.caminho.push(i);
this.delFile(item, items[i].children);
} else {
if (items.length == 1 + i) {
this.caminho.pop();
}
}
}
}
Any ideas? Feel free to optimize my code directly on CodePen if you prefer :)
EDIT: Just to clarify, my problem here is strictly on how to remove an element by the id. When the user clicks on the bin icon I know what element I need to remove, but I don't know how to take it off of the array. Map, Filter and other native JS functions cannot do that to an array of arrays/JSON, so I tought about using recursivity or something else to make it work.
You need to look at objects, not just arrays.
Let me recommend an example library. https://github.com/leezng/vue-json-pretty.
If your question about multidimensional array iteration and process i think you have to ask on javascript and/or algorithm tags.
I hope this answer will help you.
The problem was with where I placed the this.caminho.pop()
I should only do that in the "else" of the condition that compares the id of the current item with the id of the item I'm looking for.
delFile(item, items) {
for (let i = 0; i < items.length; i++) {
if (items[i].id == item.id) {
//if the current item has the same id as the item I'm looking for
//it means I found the guy and I call the function to remove it
return this.removeItem(i);
} else {
//otherwise, I keep on searching
if (items[i].children) {
//if the item on the actual index have children, I'll search among them
if (items[i].idp == "") {
//if the items doesn't have a parent, I clean the "caminho" (path) var. That var traces the route till the item I'm looking for
this.caminho = [];
}
//I push the index to the var that traces the route
this.caminho.push(i);
//I call the function back again, now with the child items
this.delFile(item, items[i].children);
}
if (items.length == 1 + i) {
//if the item's lenght has been completely coursed, I pop the index out of the var that holds the route, because at this point I know the item I'm looking for is not among them
this.caminho.pop()
}
}
}
},
Here is the solution: https://codepen.io/luizarusso/pen/zYxLOPb
Works with treeview with any deepness

Compare two arrays and update with the new values by keeping the existing objects using javascript-Not working for delete operation of objects

This is a follow up question for Compare two arrays and update with the new values by keeping the existing objects using javascript which was ansewered by #Siderite Zackwehdex
Please check this plunker I'm getting the deleted Object in the changedArray1.Is there any option to fix this.Its working fine for other changes like add,update but not for delete.
One feature that I tried to implement is to add an additional object ie., "removedIds":[23] , that holds the deleted id's as an array in each level of objects and identifying them in the evaluation process.. but didn't find the right soultion
Example data:
var parentArray1=[
{
"id": 1,
"name": "test",
"context": [
{
"operationalContextId": 1.1,
"valueChainEntityDetails": [
{
"valuChainEntityId": 3,
"name": "test",
"context": [
{
"id": 3.1,
"name": "test 3.1",
"activityDetails": [
{
"activityId": 22,
"name": "test 3.1"
},
{ //trying to remove activity id 23
"activityId": 23,
"name": "changed test 23"
}
]
}
]
}
]
}
]
}
]
var changedArray1=[
{
"id": 1,
"name": "test2",
"context": [
{
"operationalContextId": 1.1,
"valueChainEntityDetails": [
{
"valuChainEntityId": 3,
"name": "changed test3",
"context": [
{
"id": 3.1,
"name": "test 3.1",
"removedIds":[23] ,
"activityDetails": [ //activity id 23 is removed in this JSON but reflecting in parentArray1
{
"activityId": 22,
"name": "changed test 3.1"
}
]
}
]
}
]
}
]
}
]

How can I Implement recursive join using loopback self relations?

How to create parent child hierarchy using self-join in strongloop. I have created model name as menu.
menu.json
{
"name": "Menu",
"base": "PersistedModel",
"strict": false,
"idInjection": false,
"options": {
"validateUpsert": true
},
"properties": {
"MenuID": {
"type": "Number",
"id": true,
"required": true
},
"Name": {
"type": "string"
},
"ParentMenuID": {
"type": "Number"
}
},
"validations": [],
"relations": {
"menus": {
"type": "hasMany",
"model": "Menu",
"foreignKey": "ParentMenuID",
}
},
"acls": [],
"methods": {}
}
Table data like:
menuId Name ParentID
1 parent 0
2 child 1
3 grandchild 2
I tried REST API call using filter but I am getting one level of data like
http://localhost:3000/api/Menus/?filter[include]=menus
[
{
"MenuID": 1,
"Name": "parent",
"ParentMenuID": 0,
"menus": [
{
"MenuID": 2,
"Name": "child",
"ParentMenuID": 1
}
]
},
{
"MenuID": 2,
"Name": "child",
"ParentMenuID": 1,
"menus": [
{
"MenuID": 3,
"Name": "grandchild",
"ParentMenuID": 2
}
]
},
{
"MenuID": 3,
"Name": "grandchild",
"ParentMenuID": 2,
"menus": []
}
]
BUT I needed output like:
[
{
"MenuID": 1,
"Name": "parent",
"ParentMenuID": 0,
"menus": [
{
"MenuID": 2,
"Name": "child",
"ParentMenuID": 1,
"menus": [
{
"MenuID": 3,
"Name": "grandchild",
"ParentMenuID": 2
}
]
}
]
}
]
Please suggest any idea or example.
After you create your model with slc loopback:model, just run slc loopback:relation and create the selfjoin as a relation.
As you now have done in your updated question. To include another you use an include filter, http://localhost:3000/api/Menus/?filter[include]=menus and to include two levels you can do like this: http://localhost:3000/api/Menus/?filter[include][menus]=menus
Suppose you have a model review, images, and the relation that you want between them is review should have multiple images. Then you have to define this relation in the json files for both the models
Review.json
"relations": {
"images": {
"type": "hasMany",
"model": "Image",
"foreignKey": ""
}
}
Image.json
"relations": {
"hotelReview": {
"type": "belongsTo",
"model": "HotelReview",
"foreignKey": ""
}
}
You can also accomplish the same using slc loopback:relation after you create both the models.
Now in order to extract the data using this relation or join, you can use the filter api's provided by loopback, and in particular use the include provide by loopback.
Sample links for loopback include and filter api
https://docs.strongloop.com/display/public/LB/Include+filter
https://docs.strongloop.com/display/public/LB/Querying+data
sample filter api, using include :-
localhost:3000/api/Review?filter[where][email]=xyz#abc.com&filter[include]=images

Categories