I am calling my API to get JSON array below,
array = [{"date":1533791167870,"count":1,"name":"James"},{"date":1533791167870,"count":3,"name":"Kane"},{"date":1533791167918,"count":1,"name":"Kane"},{"date":1536203856526,"count":2,"name":"Trent"},{"date":1536217871371,"count":5,"name":"Kane"},{"date":1536217882525,"count":4,"name":"James"}]
And my name array,
name_array = ["Kane","Trent","James","Sam"]
I am using Lodash library. I would like to get my output array such that for each date all names are mapped from name_array and if there is count then get count value from array otherwise 0. I am expecting my output array as below result_array,
result_array = [{
"date": 1533791167870,
"count": 1,
"name": "James"
}, {
"date": 1533791167870,
"count": 3,
"name": "Kane"
},
{
"date": 1533791167870,
"count": 0,
"name": "Trent"
},
{
"date": 1533791167870,
"count": 0,
"name": "Sam"
}, {
"date": 1533791167918,
"count": 0,
"name": "James"
},
{
"date": 1533791167918,
"count": 1,
"name": "Kane"
},
{
"date": 1533791167918,
"count": 0,
"name": "Sam"
},
{
"date": 1533791167918,
"count": 0,
"name": "Trent"
}, {
"date": 1536203856526,
"count": 0,
"name": "James"
},
{
"date": 1536203856526,
"count": 0,
"name": "Kane"
},
{
"date": 1536203856526,
"count": 2,
"name": "Trent"
},
{
"date": 1536203856526,
"count": 0,
"name": "Sam"
}, {
"date": 1536217871371,
"count": 0,
"name": "James"
},
{
"date": 1536217871371,
"count": 5,
"name": "Kane"
},
{
"date": 1536217871371,
"count": 5,
"name": "Trent"
},
{
"date": 1536217871371,
"count": 5,
"name": "Sam"
}, {
"date": 1536217882525,
"count": 4,
"name": "James"
},
{
"date": 1536217882525,
"count": 0,
"name": "Trent"
}, {
"date": 1536217882525,
"count": 0,
"name": "Sam"
},
{
"date": 1536217882525,
"count": 0,
"name": "Kane"
}
]
I am doing this way for NVD3 AngularJS MultiBar chart. Since my array data is not working for the stacked view but group view is working fine.
I am using AngularJS, Lodash.
I would appreciate the help.
You can do it with several _.map calls:
let result = _.flatten(_.map(_.groupBy(array, 'date'), (existedEntries, date) => {
let usedNames = _.map(existedEntries, entry => entry.name);
let namesDiff = _.difference(name_array, usedNames);
let dateNumeric = parseFloat(date);
let enrichedNames = _.map(namesDiff, name => {
return {
date: dateNumeric,
count: 0,
name: name
};
});
return _.union(existedEntries, enrichedNames);
}));
First of all, we group existed entries by date, and for each group determine what names are used there. Then we calculate difference between all possible names and names used in the group. For each name from the difference we map it into default object with count: 0 and date equals to the date of current existing group. Next, we union existing values of the group with ones we got after enriching names diff. Final flatten call removes away temporal internal array structure.
In case if you use ES5 or lower, replace arrows syntax sugar with functions and let with var, i.e. var usedNames = _.map(existedEntries, function(entry) {return entry.name;});
P.S. In ES6 you can replace Lodash map function with eponymous native function, i.e. let usedNames = existedEntries.map(entry => entry.name);
Related
I am trying to assert value's in a requestbody which I have intercepted with cypress.
The values I need to assert are "name": "NewName", and "title": "STUB1-Draft" you can see in the requestbody example that I have attached.
My testscript in Cypress:
it.only('Check the requestbody', function () {
cy.intercept('PUT', '**/api/assessmenttest/**', req => {
req.reply({ statusCode: 200 });
}).as('NewSectionAndItem');
cy.wait('#NewSectionAndItem')
.its('request.body.test')
.its('testParts')
.its('testSections')
.its('name')
.should('include', 'NewName');
//cy.wait('#NewSectionAndItem').its('request.body.testParts').expect(arr_obj[1].name).to.equal('NewName')
The request body look like the following:
{
"structureStatistics": {
"testPartCount": 1,
"testSectionCount": 6,
"itemCount": 23
},
"name": "BIMMA",
"title": "OTAP",
"correctionInstructionsUrl": "C:Stub/FakePath/For/Cypress",
"correctionInstructionAppendices": [],
"testParts": [
{
"testSections": [
{
"order": 1,
"name": "Tekst 1 Looking for the one? ",
"itemReferences": [
{
"itemId": "55eb5a28-24d8-4705-b465-8e1454f73ac8",
"weight": 11,
"neutralisationType": "NoNeutralisation",
"itemSummary": {
"id": "55eb5a28-24d8-4705-b465-8e1454f73ac8",
"title": "H-E-T1-1"
}
}
],
"id": "5c3eef2d-1094-4b9e-84c1-f184956f87fa"
},
{
"id": "ffaebc93-0bf6-4f75-944a-f61345a7be90",
"name": "NewName",
"itemReferences": [
{
"itemId": "58a29037-c92c-48f6-a7c3-a2f94e288992",
"weight": 0,
"neutralisationType": "NoNeutralisation",
"itemSummary": {
"id": "58a29037-c92c-48f6-a7c3-a2f94e288992",
"title": "STUB1-Draft",
"state": "Draft"
}
}
]
},
{
"order": 2,
"name": "Tekst 2 The fruit Iron Ox bears",
"itemReferences": [
{
"itemId": "abfc0811-26c7-4d9d-b3cc-0c920e5af259",
"weight": 2,
"neutralisationType": "NoNeutralisation",
"itemSummary": {
"id": "abfc0811-26c7-4d9d-b3cc-0c920e5af259",
"title": "H-E-T2-2"
}
},
{
"itemId": "3cfda5e0-0d64-44ef-8a4d-21f37484c024",
"weight": 12,
"neutralisationType": "NoNeutralisation",
"itemSummary": {
"id": "3cfda5e0-0d64-44ef-8a4d-21f37484c024",
"title": "H-E-T2-3"
}
},
{
"itemId": "19ba8a53-9755-4beb-8f69-edd107b80230",
"weight": 1,
"neutralisationType": "NoNeutralisation",
"itemSummary": {
"id": "19ba8a53-9755-4beb-8f69-edd107b80230",
"title": "H-E-T2-4"
}
},
{
"itemId": "3f5b7b81-df1f-4f01-8165-cb2226d9044d",
"weight": 1,
"neutralisationType": "NoNeutralisation",
"itemSummary": {
"id": "3f5b7b81-df1f-4f01-8165-cb2226d9044d",
"title": "H-E-T2-5"
}
}
],
"id": "00f7455e-6d7d-4311-80cd-eff45c83ef2c"
},
{
"order": 3,
"name": "Tekst 3 How to live like a tramp",
"itemReferences": [
{
"itemId": "7e2d568c-4cde-4500-9c6b-c09f246155e4",
"weight": 1,
"neutralisationType": "NoNeutralisation",
"itemSummary": {
"id": "7e2d568c-4cde-4500-9c6b-c09f246155e4",
"title": "H-E-T3-6"
}
},
{
"itemId": "87a5bf1c-451a-40b8-802a-53ee842cafcd",
"weight": 1,
"neutralisationType": "NoNeutralisation",
"itemSummary": {
"id": "87a5bf1c-451a-40b8-802a-53ee842cafcd",
"title": "H-E-T3-7"
}
}
],
"id": "390ecc2e-6715-4898-aaea-158e790525a2"
}
],
"navigationMode": "Linear",
"submissionMode": "Individual",
"id": "a546a67c-ac39-4e81-bf03-beb482c920a0"
}
],
"metadataToBePublished": [
"be63002c-dcf8-449f-a0ae-6ba50d4e2712",
"4d70239e-7a6e-47c3-b157-462d6c8c5edc"
],
"created": "2022-07-08T09:00:00+00:00",
"modified": "2022-09-21T23:55:58.6532451+02:00",
"createdBy": {
"id": "a45ea6db-bf04-427d-9354-7081b7592a3d",
"fullName": "Manual Construction"
},
"lastModifiedBy": {
"id": "129a584c-a677-4d9f-b289-019d1815064f",
"fullName": "OZKAN"
},
"id": "300eea01-ee10-4bd9-9356-8aaa933e949c"
}
I could not figure out how I can assert nested arrays and value's, without using deep.equal for the complete request. Thank you indeed!
It basically just looks like a couple of things
an extra test property in the test that's not there in the request
testParts and testSections are arrays (square bracket instead of curly bracket), so you need an index for them
Generally I think this would work
cy.wait('#NewSectionAndItem')
.its('request.body')
.its('testParts.0')
.its('testSections.1')
.its('name')
.should('include', 'NewName');
The problem is identifying the correct array indexes. testParts has only one element, so 0 is the only index option there.
To find the testSection index, create a dummy .json file in VS Code (or other editor) paste in the json from above and use the collapse toggles on the left to easily see which index contains the value you seek.
You can use a cy-spok plugin to make a spok assertion to easily check a nested property.
Example use
const spok = require('cy-spok')
// later in your test
cy.wait('#NewSectionAndItem')
.its('request.body')
.should(spok({
test: {
testParts: {
testSections: {
name: 'NewName',
title: 'STUB1-Draft'
}
}
}
});
I have an array :
{
"count": 8,
"id": "accountId",
"name": " Account Id",
"values": [
{
"count": 2,
"id": "1234456789000",
"name": "1234456789000"
},
{
"count": 1,
"id": "135792468045",
"name": "135792468045"
},
{
"count": 1,
"id": "309983110022",
"name": "309983110022"
},
{
"count": 2,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 1,
"id": "6ee26149-a156-4665-bd26-a6e46b49a70f",
"name": "6ee26149-a156-4665-bd26-a6e46b49a70f"
},
{
"count": 1,
"id": "927b48ce-efe4-4c20-98f0-ec6c54f59b45",
"name": "927b48ce-efe4-4c20-98f0-ec6c54f59b45"
}
]
}
And I have a 2nd array :
[
{
"count": 2,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 2,
"id": "1234456789000",
"name": "1234456789000"
}
]
The second array, I have filtered based on some requirement.
I want to replace the values from 1st array with second array.
Using typescript code.
Please help here.
If I understand question, you just need iterate by values array and find same id from second array.
function findAndSwitch(object1, array1): void {
object1.values = object1.values.map(el => {
const objToSwitch = array1.find(eleArr => eleArr.id === el.id);
if (objToSwitch) {
return el = objToSwitch;
} else {
return el;
}
});
}
https://stackblitz.com/edit/typescript-dvty4p
Let's say your variable names are obj1 and arr2, respectively. First transform arr2 into an object obj2:
let obj2 = arr2.reduce((acc,cur) => ({...acc,[cur.id]:cur}),{});
Which now looks like this:
{
'432112426686': {
count: 20,
id: '432112426686',
name: '432112426686'
},
'1234456789000': {
count: 20,
id: '1234456789000',
name: '1234456789000'
}
}
Then transform obj1 based on obj2 as follows:
obj1.values = obj1.values.map(value => obj2[value.id] || value);
Please note that since the data in arr2 is identical to the corresponding data in obj1, I have altered the values of count property in arr2 in order to demonstrate that obj1 will be updated accordingly.
DEMO ONE
let obj1 = {
"count": 8,
"id": "accountId",
"name": " Account Id",
"values": [
{
"count": 2,
"id": "1234456789000",
"name": "1234456789000"
},
{
"count": 1,
"id": "135792468045",
"name": "135792468045"
},
{
"count": 1,
"id": "309983110022",
"name": "309983110022"
},
{
"count": 2,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 1,
"id": "6ee26149-a156-4665-bd26-a6e46b49a70f",
"name": "6ee26149-a156-4665-bd26-a6e46b49a70f"
},
{
"count": 1,
"id": "927b48ce-efe4-4c20-98f0-ec6c54f59b45",
"name": "927b48ce-efe4-4c20-98f0-ec6c54f59b45"
}
]
};
let arr2 = [
{
"count": 20,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 20,
"id": "1234456789000",
"name": "1234456789000"
}
];
let obj2 = arr2.reduce((acc,cur) => ({...acc,[cur.id]:cur}),{});
obj1.values = obj1.values.map(value => obj2[value.id] || value);
console.log( obj1 );
--
However, if all you want is to replace all the obj1.values with arr2, all you need is:
obj1.values = [...arr2];
And this will give rise to:
{
count: 8,
id: 'accountId',
name: ' Account Id',
values: [{
count: 20,
id: '432112426686',
name: '432112426686'
},
{
count: 20,
id: '1234456789000',
name: '1234456789000'
}
]
}
DEMO TWO
let obj1 = {
"count": 8,
"id": "accountId",
"name": " Account Id",
"values": [
{
"count": 2,
"id": "1234456789000",
"name": "1234456789000"
},
{
"count": 1,
"id": "135792468045",
"name": "135792468045"
},
{
"count": 1,
"id": "309983110022",
"name": "309983110022"
},
{
"count": 2,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 1,
"id": "6ee26149-a156-4665-bd26-a6e46b49a70f",
"name": "6ee26149-a156-4665-bd26-a6e46b49a70f"
},
{
"count": 1,
"id": "927b48ce-efe4-4c20-98f0-ec6c54f59b45",
"name": "927b48ce-efe4-4c20-98f0-ec6c54f59b45"
}
]
};
let arr2 = [
{
"count": 20,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 20,
"id": "1234456789000",
"name": "1234456789000"
}
];
obj1.values = arr2;
console.log( obj1 );
I'm storing data in a JSON file and need different objects/arrays. So far I am using the following structure:
data= [
{
"savedRuns": [
{
"id": 1,
"name": "Run 1"
},
{
"id": 2,
"name": "Run 2"
},
{
"id": 3,
"name": "Run 3"
}
]
},
{
"groups": [
{
"id": 1,
"name": "g1"
},
{
"id": 2,
"name": "g2"
},
{
"id": 3,
"name": "g3"
}
]
},
{
"locations": [
{
"id": 1,
"name": "home"
},
{
"id": 2,
"name": "work"
},
{
"id": 3,
"name": "school"
}
]
}
]
I would like to access the data in the file in an easy way, for instance:
console.log(data.savedRuns)
console.log(data.locations)
Unfortunately this returns undefined and the only way to access the data is:
console.log(data[0].savedRuns);
console.log(data[2].locations);
Since I don't necessarily know the position of the object, I would like to avoid that. If there a way around this, or a different structure to adopt for my file?
Link to JSFiddle
You have each attribute in a separate object, stored in an array. Get rid of the outer array and store the attributes in one object, then use data.savedRuns.
Thanks to Marks answer I could get the right syntax. Posting below in case of interest to others.
data = {
"savedRuns": [{
"id": 1,
"name": "Run 1"
},
{
"id": 2,
"name": "Run 2"
},
{
"id": 3,
"name": "Run 3"
}
],
"groups": [{
"id": 1,
"name": "g1"
},
{
"id": 2,
"name": "g2"
},
{
"id": 3,
"name": "g3"
}
],
"locations": [{
"id": 1,
"name": "home"
},
{
"id": 2,
"name": "work"
},
{
"id": 3,
"name": "school"
}
]
}
Well, i have a complicated issue. at least it is complicated for myself.
So i have an Array which has an Array that has an Array in it.
and i want to filter The very top array based on properties inside the deepest array.
Lets say i have this Array of objects
var garages = [{
"GarageId": 1,
"GarageName": "Garage_001",
"Sections": [{
"SectionId": 1,
"Name": "Section_002",
"Cars": [{
"Id": 5,
"Model": "Bmw"
}, {
"Id": 6,
"Model": "Mercedes"
}]
}, {
"SectionId": 2,
"Name": "Section_003",
"Cars": [{
"Id": 8,
"Model": "Toyota"
}, {
"Id": 6,
"Model": "Mercedes"
}]
}]
},
{
"GarageId": 6,
"GarageName": "Garage_006",
"Sections": [{
"Id": 1,
"Name": "Section_007",
"Cars": [{
"Id": 5,
"Model": "Bmw"
}, {
"Id": 6,
"Model": "Mercedes"
}]
}, {
"Id": 2,
"Name": "Section_003",
"Cars": [{
"Id": 8,
"Model": "Toyota"
}, {
"Id": 6,
"Model": "Mercedes"
}]
}]
}
]
And i want to retrieve a list of garages that contain a Hyundai for example. how can i do it?
i have been trying for hours and this is what i came up with. it may be a stupid piece of code but i just got confused dealing with this much nested Arrays!
So my code is this:
garages: any[] = [];
selectedCarModel: number: 8;
filterOnCarModel(carId) {
this.garages = getGaragesFromServed();
this.selectedCarModel = this.CarModels.find(c => c.Id == id);
let filteredArray = this.garages
.filter((garage) =>
garage.Sections).
filter((section) =>
study.Cars.find((car) => car.Id == carId));
this.garages = filteredArray;
}
Thank you for understanding
var filteredGarages = garages.filter(garage =>
garage.Sections.filter(section =>
section.Cars.filter(car => car.Model.indexOf("Bmw")>=0)
.length > 0)
.length > 0)
I am using Typescript for below problem. I want to search object not simple alphabetic or number in the list.
Below are the two arrays.
I want to get common objects in separate list without using any third party library.
firstArray = [
{
"id": 4,
"name": "Tata"
},
{
"id": 11,
"name": "Maruti"
},
{
"id": 14,
"name": "Mahindra"
}
]
secondArray = [
{
"id": 4,
"name": "Tata"
},
{
"id": 11,
"name": "Maruti"
},
{
"id": 15,
"name": "Hyundai"
},
{
"id": 21,
"name": "Honda"
}
]
// Get Common Elements
// I am getting blank array as output
console.log(firstArray.filter(( make ) => secondArray.includes( make)));
Is there good function or way to find out commons element?
You can use array#filter with array#some. For each object in the first array, check if id and name exist in the other array.
const firstArray = [{ "id": 4, "name": "Tata" }, { "id": 11, "name": "Maruti" }, { "id": 14, "name": "Mahindra" } ],
secondArray = [{ "id": 4, "name": "Tata" }, { "id": 11, "name": "Maruti" }, { "id": 15, "name": "Hyundai" }, { "id": 21, "name": "Honda" } ],
result = firstArray.filter(o => secondArray.some(({id,name}) => o.id === id && o.name === name));
console.log(result);
For ES6, you can also try sets,
For demonstration,
const thirdArray = [...new Set([...firstArray ,...secondArray])];