Compare 3 arrray and find combination in javascript - javascript

I have 3 arrays as below
A: [
{
"label": "100Watts",
"value": "100Watts",
},
{
"label": "135Watts",
"value": "135Watts",
} ]
B: [
{
"label": "Large|100cm",
"value": "Large|100cm"
},
{
"label": "Small|125mm",
"value": "Small|125mm"
}
]
C: [
{
"label": "Black",
"value": "Black",
},
{
"label": "Black",
"value": "Black",
}
]
I have one master array as below
result:[
{
"x_powerConsumption": "100Watts",
"x_size": "Small|125mm",
"x_color": "Black",
},
{
"x_powerConsumption": "135Watts",
"x_size": "Large|100cm",
"x_color": "Black",
}
]
My code as below
let newArray = A.filter(o1 => result.some(o2 => o1.label === o2.x_size));
let newArray2 = B.filter(o1 => result.some(o2 => o1.label === o2.x_powerConsumption));
this.setState({selectedVarientOne: newArray[0].label, selectedVarientTwo:newArray2[0].label})
But my requirement is i need combination as below like
Output : Black --> 100Watts --> Small|125mm
But as per my above code it is coming like
Black --> 100Watts --> Large|100mm
Can anyone tell me how i can solve this?

Ok, I'm assuming that you want to match the array of objects to the main object
I just use a nest of for loops to see if values from an array(A,B, or C) match up with values from the main object(result) from only the important keys in the result object of course
var A=[{"label":"100Watts","value":"100Watts"},{"label":"135Watts","value":"135Watts"}]
var B=[{"label":"Large|100cm","value":"Large|100cm"},{"label":"Small|125mm","value":"Small|125mm"}]
//now for function to correlate data(sry for late answer was afk lol)
function attribute(arr,result){
const necessary_keys=["x_powerConsumption","x_size","x_color"]
var toReturn=[] //array with output to return
for(let i=0;i<arr.length;i++){
var arrValues=Object.values(arr[i]) //eg: A[0] would be ["100Watts","100Watts"]
for(let j=0;j<result.length;j++){
var resultValues=Object.keys(result[j])
.filter(key=>necessary_keys.includes(key))
.map(key=>result[j][key]) //result[0] would be ["100Watts","Small|125mm","Black"]
if(resultValues.some(value=>arrValues.includes(value))){
toReturn[i]=resultValues //["100Watts","Small|125mm","Black"] for arr[0]
}
}
}
return toReturn //all indexes with undefined dont correlate with result in any of its values
}
//now to use the function
let newArray=attribute(A,result)
let newArray2=attribute(B,result)
console.log("values from A:",newArray)
console.log("values from B:",newArray2)
<script>
var result=[
{
"dynamicPropertyMapLong": {
"sku-Equipment_x_color": 1,
"sku-Equipment_x_size": 1,
"sku-Equipment_x_powerConsumption": 3
},
"x_UAE_installationPrice": 0,
"bundleLinks": [],
"largeImage": null,
"smallImage": null,
"listVolumePrice": null,
"onlineOnly": false,
"listPrices": {
"aed": 100,
"loyaltyProgram": null
},
"configurationMetadata": [],
"largeImageURLs": [],
"x_skuCreationDate": null,
"productLine": null,
"listVolumePrices": {
"aed": null,
"loyaltyProgram": null
},
"derivedSalePriceFrom": "aed",
"model": null,
"x_powerConsumption": "100Watts",
"barcode": null,
"salePriceEndDate": null,
"images": [],
"unitOfMeasure": null,
"primaryMediumImageURL": null,
"dynamicPropertyMapBigString": {},
"active": true,
"x_promotionDetails": "5 Percent Off: 5OFF5",
"thumbImageURLs": [],
"mediumImageURLs": [],
"primarySourceImageURL": null,
"x_description": null,
"sourceImageURLs": [],
"primarySmallImageURL": null,
"x_autoShipPrice": 0,
"productFamily": null,
"primaryThumbImageURL": null,
"nonreturnable": false,
"x_loyaltyLevel": "LEVEL2",
"displayName": "Three variant sku1",
"salePrices": {
"aed": null,
"loyaltyProgram": null
},
"primaryFullImageURL": null,
"productListingSku": null,
"primaryLargeImageURL": null,
"derivedOnlineOnly": false,
"smallImageURLs": [],
"thumbnailImage": null,
"saleVolumePrices": {
"aed": null,
"loyaltyProgram": null
},
"x_size": "Small|125mm",
"saleVolumePrice": null,
"salePriceStartDate": null,
"quantity": null,
"salePrice": null,
"fullImageURLs": [],
"x_isonSale": "Y",
"variantValuesOrder": {},
"x_color": "Black",
"soldAsPackage": true,
"listingSKUId": null,
"x_SAR_installationPrice": 0,
"repositoryId": "300003-1",
"derivedListPriceFrom": "aed",
"x_installationPrice": 0,
"x_costPrice": null,
"configurable": false,
"listPrice": 100
},
{
"dynamicPropertyMapLong": {
"sku-Equipment_x_color": 1,
"sku-Equipment_x_size": 2,
"sku-Equipment_x_powerConsumption": 1
},
"x_UAE_installationPrice": 0,
"bundleLinks": [],
"largeImage": null,
"smallImage": null,
"listVolumePrice": null,
"onlineOnly": false,
"listPrices": {
"aed": 135,
"loyaltyProgram": null
},
"configurationMetadata": [],
"largeImageURLs": [],
"x_skuCreationDate": null,
"productLine": null,
"listVolumePrices": {
"aed": null,
"loyaltyProgram": null
},
"derivedSalePriceFrom": "aed",
"model": null,
"x_powerConsumption": "135Watts",
"barcode": null,
"salePriceEndDate": null,
"images": [],
"unitOfMeasure": null,
"primaryMediumImageURL": null,
"dynamicPropertyMapBigString": {},
"active": true,
"x_promotionDetails": "5 Percent Off: 5OFF5",
"thumbImageURLs": [],
"mediumImageURLs": [],
"primarySourceImageURL": null,
"x_description": null,
"sourceImageURLs": [],
"primarySmallImageURL": null,
"x_autoShipPrice": 0,
"productFamily": null,
"primaryThumbImageURL": null,
"nonreturnable": false,
"x_loyaltyLevel": "LEVEL2",
"displayName": "sku3",
"salePrices": {
"aed": null,
"loyaltyProgram": null
},
"primaryFullImageURL": null,
"productListingSku": null,
"primaryLargeImageURL": null,
"derivedOnlineOnly": false,
"smallImageURLs": [],
"thumbnailImage": null,
"saleVolumePrices": {
"aed": null,
"loyaltyProgram": null
},
"x_size": "Large|100cm",
"saleVolumePrice": null,
"salePriceStartDate": null,
"quantity": null,
"salePrice": null,
"fullImageURLs": [],
"x_isonSale": "Y",
"variantValuesOrder": {},
"x_color": "Black",
"soldAsPackage": true,
"listingSKUId": null,
"x_SAR_installationPrice": 0,
"repositoryId": "300003-3",
"derivedListPriceFrom": "aed",
"x_installationPrice": 0,
"x_costPrice": null,
"configurable": false,
"listPrice": 135
}
]
</script>

Assuming the other answer is correct, here is a shorter version:
result.map(({x_powerConsumption, x_size, x_color}) => ([
A.find(el => el.label === x_powerConsumption).value,
B.find(el => el.label === x_size).value,
C.find(el => el.label === x_color).value
]))
Example:
const A = [{ "label": "100Watts", "value": "100Watts" }, { "label": "135Watts", "value": "135Watts" }];
const B = [{ "label": "Large|100cm", "value": "Large|100cm" }, { "label": "Small|125mm", "value": "Small|125mm" }];
const C = [{ "label": "Black", "value": "Black" }, { "label": "Black", "value": "Black" }];
const result = [
{ "x_powerConsumption": "100Watts", "x_size": "Small|125mm", "x_color": "Black" },
{ "x_powerConsumption": "135Watts", "x_size": "Large|100cm", "x_color": "Black" }
];
console.log(result.map(({x_powerConsumption, x_size, x_color}) => ([
A.find(el => el.label === x_powerConsumption).value,
B.find(el => el.label === x_size).value,
C.find(el => el.label === x_color).value
])));

Related

Add new property to react state

I am trying to add a new property to the state "initialTags". However, I do not know how to do that. I have tried to loop through the object to set the new property, however it didnt work. Also, the setState it all in a same function, but since setState is async, I am unable to setState on the same state after my first setState statement.
Initializing the state:
this.setState({ initialTags: [...tempTarget] }, () => console.log("initTags == ", this.state.initialTags));
Array of Object after setState:
[
{
"name": "AQS",
"projectId": "MTYzMDE1MzU3NjA3My10ZXN0MTA",
"projectName": null,
"isUserForAllProject": false
},
{
"name": "ED",
"projectId": null,
"projectName": null,
"isUserForAllProject": null
},
{
"name": "PAID",
"projectId": null,
"projectName": null,
"isUserForAllProject": null
},
{
"name": "QS",
"projectId": null,
"projectName": null,
"isUserForAllProject": null
}
]
The New property that needs to be added in the Object:
[
{
"name": "AQS",
"projectId": "MTYzMDE1MzU3NjA3My10ZXN0MTA",
"projectName": null,
"isUserForAllProject": false,
"return": []
},
{
"name": "ED",
"projectId": null,
"projectName": null,
"isUserForAllProject": null,
"return": []
},
{
"name": "PAID",
"projectId": null,
"projectName": null,
"isUserForAllProject": null,
"return": []
},
{
"name": "QS",
"projectId": null,
"projectName": null,
"isUserForAllProject": null,
"return": []
}
]
EDIT: SOLUTION
this.setState({ initialTags: [...tempTarget.map(item => ({...item, returnVal: []}))] })
this.setState((prev) => {
return {
...prev,
initialValues: prev.initialValues.map((item) => {
return {
...item,
returnValue: []
};
})
};
});
You shoudn't use return as it is a keyword.

Create a level for each object in the flatenned tree

I want to implement a Angular material flat tree. I am new to reduce function and closure understanding the below method is also difficult for me. Can it be simplified I am using the below code to flatten a recursive tree. My tree look as below and I can rewrite the flattened code with level included. How do I incorporate level here. How can this be achieved, Please help.
[ {
"sectionIdent": "0/0",
"examSectionID": "59f87638-a4ce-4861-81f9-562a887ba3e5",
"sectionTitle": "Timed exam section 1",
"sectionOrder": null,
"randomCount": null,
"mixContent": null,
"totalCount": 0,
"titleError": false,
"randomError": false,
"items": null,
"delNavInfo": null,
"subExamSections": [{
"sectionIdent": "0/0/0",
"examSectionID": "59f87638-a4ce-4861-81f9-562a887ba3e5",
"sectionTitle": "Timed exam section 2",
"sectionOrder": null,
"randomCount": null,
"mixContent": null,
"totalCount": 0,
"titleError": false,
"randomError": false,
"items": null,
"delNavInfo": null,
"subExamSections": [],
"mainSection": true
},
{
"sectionIdent": "0/0/1",
"examSectionID": "59f87638-a4ce-4861-81f9-562a887ba3e5",
"sectionTitle": "Timed exam section 3",
"sectionOrder": null,
"randomCount": null,
"mixContent": null,
"totalCount": 0,
"titleError": false,
"randomError": false,
"items": null,
"delNavInfo": null,
"subExamSections": [{
"sectionIdent": "0/0/1/0",
"examSectionID": "59f87638-a4ce-4861-81f9-562a887ba3e5",
"sectionTitle": "Timed exam section 4",
"sectionOrder": null,
"randomCount": null,
"mixContent": null,
"totalCount": 0,
"titleError": false,
"randomError": false,
"items": null,
"delNavInfo": null,
"subExamSections": null,
"mainSection": true
}
],
"mainSection": true
}
],
"mainSection": true
}
];
I want it in the format like this
[{
...sectionTitle:"Timed exam section 1",
level:0
},
{
...sectionTitle:"Timed exam section 2",
level:1
},
{
...sectionTitle:"Timed exam section 3",
level:1
},
{
...sectionTitle:"Timed exam section 4",
level:2
},
]
Code:
buildFileTree(nodeArray: any, level: number): ExamSection[] {
return nodeArray.reduce(function recur(accumulator, curr) {
var keys = Object.keys(curr);
keys.splice(keys.indexOf('subExamSections'), 1);
accumulator.push(keys.reduce(function (entry, key) {
entry[key] = curr[key];
return entry;
}, {}));
if (curr.subExamSections && curr.subExamSections.length) {
return accumulator.concat(curr.subExamSections.reduce(recur, []));
}
return accumulator;
}, []);
}
You can get the structure you are looking for with this:
function buildFileTree(tree = [], level = 0) {
return Array.prototype.concat
.apply(
tree.map(item => ({ ...item, level })), // Add 'level' property
tree.map(item => {
const subtree = item.subExamSections || []
const nextLevel = level + 1
return buildFileTree(subtree, nextLevel) // Combine with sub-tree recursively
})
)
.map(({ sectionTitle, level }) => ({ sectionTitle, level })) // Extract the desired properties
}
Concetp used :
... Destructuring to add and remove properties,
Recussiong: for looping,
map to create new array,
foreach to iteration.
let loop = (sections = [], flatSection = []) => {
if(sections) {
let editedShallowCopy = sections.map((s, i) => {
let { subExamSections , ...rest } = s; // destructure to remove property
return { ...rest, level: flatSection.length + i + 1 } // adding the new property
});
flatSection.push(...editedShallowCopy); // adding it flatSection
sections?.forEach(section => loop(section.subExamSections, flatSection)); // go in deeper levels of tree, Recussiong loop
}
return flatSection;
}
console.log(loop(tree))
let tree = [{
"sectionIdent": "0/0",
"examSectionID": "59f87638-a4ce-4861-81f9-562a887ba3e5",
"sectionTitle": "Timed exam section 1",
"sectionOrder": null,
"randomCount": null,
"mixContent": null,
"totalCount": 0,
"titleError": false,
"randomError": false,
"items": null,
"delNavInfo": null,
"subExamSections": [{
"sectionIdent": "0/0/0",
"examSectionID": "59f87638-a4ce-4861-81f9-562a887ba3e5",
"sectionTitle": "Timed exam section 2",
"sectionOrder": null,
"randomCount": null,
"mixContent": null,
"totalCount": 0,
"titleError": false,
"randomError": false,
"items": null,
"delNavInfo": null,
"subExamSections": [],
"mainSection": true
},
{
"sectionIdent": "0/0/1",
"examSectionID": "59f87638-a4ce-4861-81f9-562a887ba3e5",
"sectionTitle": "Timed exam section 3",
"sectionOrder": null,
"randomCount": null,
"mixContent": null,
"totalCount": 0,
"titleError": false,
"randomError": false,
"items": null,
"delNavInfo": null,
"subExamSections": [{
"sectionIdent": "0/0/1/0",
"examSectionID": "59f87638-a4ce-4861-81f9-562a887ba3e5",
"sectionTitle": "Timed exam section 4",
"sectionOrder": null,
"randomCount": null,
"mixContent": null,
"totalCount": 0,
"titleError": false,
"randomError": false,
"items": null,
"delNavInfo": null,
"subExamSections": null,
"mainSection": true
}
],
"mainSection": true
}
],
"mainSection": true
}];
let loop = (sections = [], flatSection = []) => {
if (sections) {
let editedShallowCopy = sections.map((s, i) => {
let {
subExamSections,
...rest
} = s; // destructure to remove property
return { ...rest,
level: flatSection.length + i + 1
} // adding the new property
});
flatSection.push(...editedShallowCopy); // adding it flatSection
sections.forEach(section => loop(section.subExamSections, flatSection)); // go in deeper levels of tree
}
return flatSection;
}
console.log(loop(tree))

How to filter an array of objects based on specific objects

I am trying to 'filter' this array of objects to only get the newCases and date. Moreover, I would like to convert this into a DataSet with x being the date and y being newCases.
"actualsTimeseries": [
{
"cases": 1,
"deaths": 0,
"positiveTests": null,
"negativeTests": null,
"contactTracers": null,
"hospitalBeds": {
"capacity": null,
"currentUsageTotal": null,
"currentUsageCovid": null
},
"icuBeds": {
"capacity": null,
"currentUsageTotal": null,
"currentUsageCovid": null
},
"newCases": null,
"newDeaths": null,
"vaccinesAdministeredDemographics": null,
"vaccinationsInitiatedDemographics": null,
"date": "2020-03-09"
},
{
"cases": 3,
"deaths": 0,
"positiveTests": null,
"negativeTests": null,
"contactTracers": null,
"hospitalBeds": {
"capacity": null,
"currentUsageTotal": null,
"currentUsageCovid": null
},
"icuBeds": {
"capacity": null,
"currentUsageTotal": null,
"currentUsageCovid": null
},
"newCases": 2,
"newDeaths": 0,
"vaccinesAdministeredDemographics": null,
"vaccinationsInitiatedDemographics": null,
"date": "2020-03-10"
},
{
"cases": 3,
"deaths": 0,
"positiveTests": null,
"negativeTests": null,
"contactTracers": null,
"hospitalBeds": {
"capacity": null,
"currentUsageTotal": null,
"currentUsageCovid": null
},
"icuBeds": {
"capacity": null,
"currentUsageTotal": null,
"currentUsageCovid": null
},
"newCases": 0,
"newDeaths": 0,
"vaccinesAdministeredDemographics": null,
"vaccinationsInitiatedDemographics": null,
"date": "2020-03-11"
},
...
}
I have attempted to do this, but need help on how to sort the dates.
const dataArray = actualsTimeseries.map((info) => info);
const getPastCases = () =>
Object.entries(dataArray).sort(([date1], [date2]) =>
date1.localeCompare(date2)
);
const DataSet = (casesByDate) =>
casesByDate.map(([dateString, cases]) => ({
x: new Date(dateString),
y: cases.newCases,
}));
const resData = DataSet(getPastCases());

Comparison between two Arrays of Objects failing when item is deleted

I have the following function that should determine which elements in a nested object were changed, deleted or added:
static modifiedDiff(o1, o2, deep = false, added = [], updated = [], removed = [], path = "", key = "") {
path += key.length > 0 ? key + "." : '';
for (const prop in o1) {
if (o1.hasOwnProperty(prop)) {
const o2PropValue = o2[prop];
const o1PropValue = o1[prop];
if (o2.hasOwnProperty(prop)) {
if (o2PropValue === o1PropValue) {
//unchanged[prop] = o1PropValue;
} else {
if (deep && this.isObject(o1PropValue) && this.isObject(o2PropValue)) {
this.modifiedDiff(o1PropValue, o2PropValue, deep, added, updated, removed, path, this.modifyPropIfNeeded(prop));
} else {
this.addObjectToArray(updated, path + prop, o2PropValue);
}
}
} else {
this.addObjectToArray(removed, path + prop, o1PropValue);
}
}
}
for (const prop in o2) {
if (o2.hasOwnProperty(prop)) {
const o1PropValue = o1[prop];
const o2PropValue = o2[prop];
if (o1.hasOwnProperty(prop)) {
if (o1PropValue !== o2PropValue) {
if (!deep || !this.isObject(o1PropValue)) {
//updated[prop].oldValue = o1PropValue;
}
}
} else {
this.addObjectToArray(added, path + prop, o2PropValue);
}
}
}
return {
added,
updated,
removed
};
}
This works fine for changes, and elements that are added to the second object.
The result looks like this:
{
"added": [
{
"_objects.4": {
"type": "textbox",
"version": "4.1.0",
"originX": "center",
"originY": "center",
"left": 10,
"top": 10,
"width": 84.51,
"height": 45.2,
"fill": "#000000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeDashOffset": 0,
"strokeLineJoin": "miter",
"strokeMiterLimit": 4,
"scaleX": 0.5,
"scaleY": 0.5,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"backgroundColor": "",
"fillRule": "nonzero",
"paintFirst": "fill",
"globalCompositeOperation": "source-over",
"skewX": 0,
"skewY": 0,
"text": "hallo",
"fontSize": 40,
"fontWeight": "",
"fontFamily": "helvetica",
"fontStyle": "",
"lineHeight": 1.16,
"underline": false,
"overline": false,
"linethrough": false,
"textAlign": "left",
"textBackgroundColor": "",
"charSpacing": 0,
"minWidth": 20,
"splitByGrapheme": false,
"id": "text_835392",
"styles": {}
}
}
],
"updated": [
{
"_objects.1.left": 372.81
},
{
"_objects.1.top": 179.99
}
],
"removed": []
}
The problem is the following:
If one element in an array of o2 is deleted, every element of that array moves one index forward.
This results in all elements after the deleted element to be moved into the changed or added array.
Example:
modifiedDiff([1,2,3,4], [1,2,4])
should be:
{
"added": [],
"updated": [],
"removed": [
{
"2": 3
}
]
}
but is:
{
"added": [],
"updated": [
{
"2": 4
}
],
"removed": [
{
"3": 4
}
]
}
Any ideas? Thanks for your help!

Customize JSON data with JavaScript

I am creating project using nodejs and angularjs. I have json like:
[{
"links": [{
"description": null,
"latency": "1",
"linkid": "26149e91-f6c8-47fb-a10d-691e76486871",
"contracts": null,
"tag": null,
"connections": [
"ce00ba7c-4916-4920-a7dc-7b70daea9e7a",
"6d3ec325-4b27-4772-b0d9-36d4cc7b9e47"
],
"type": "0",
"linkStatus": 1,
"bandwitdth": 799999
}, {
"description": null,
"latency": "1",
"linkid": "2f11f857-251f-4b01-9140-12abfda8d79b",
"contracts": null,
"tag": null,
"connections": [
"bcdc3622-f0b3-4bf2-80fd-3aaee5af1c4c",
"ca059990-937e-4b29-8a21-615244d56689"
],
"type": "0",
"linkStatus": 1,
"bandwitdth": 1024
}, {
"description": null,
"latency": "1",
"linkid": "7cf69528-13bc-4b90-b952-549fbbab1032",
"contracts": null,
"tag": null,
"connections": [
"b164c679-f9d9-406d-94a8-b85b99a03bdc",
"616e4bce-592e-4864-b9f6-149f541fc7d1"
],
"type": "0",
"linkStatus": 1,
"bandwitdth": 1024
}, {
"description": null,
"latency": "1",
"linkid": "d6b67215-6ca5-4f63-8573-e952c132d4af",
"contracts": null,
"tag": null,
"connections": [
"ebe0a008-29d2-48f9-bd71-4324a0712618",
"bc36697a-4768-46a1-8e05-62376103b476"
],
"type": "0",
"linkStatus": 1,
"bandwitdth": 1024
}, {
"description": "TestFlow",
"latency": "1",
"linkid": "fd73608aa8e7b440",
"contracts": null,
"tag": null,
"connections": [
"49b33cd1-5722-4e8e-b40c-03c3407c5efe",
"cd354769-d52a-414e-bb7c-f0e0690ddf3b"
],
"type": "0",
"linkStatus": 6,
"bandwitdth": 0
}],
"billing-uuid": "5f1dd7c5-c48b-44ed-be14-cf2a8730fe27"
}]
I need connections in other json. It should be like:
[{
"conn":"49b33cd1-5722-4e8e-b40c-03c3407c5efe"
},
{
"conn":"49b33cd1-5722-4e8e-b40c-03c3407c5efe"
}]
}
My code is like:
var billinData = [];
var connections = [];
for(i = 0; i < body.length; i++){
billingData.push({"billing-account-uuid":body[i]['billing-uuid']})
var nLinksLen = body[i].links.length;
for (j = 0; j < nLinksLen; j++){
var nConLen = body[i].links[j].connections.length
console.log(nConLen)
for (k = 0; k < nConLen; k++){
connections.push({"vportuuid": body[i].links[j].connections[k]});
}
}
}
I am getting this with thousand of records with some of duplicates:
[
{
"conn": "ce00ba7c-4916-4920-a7dc-7b70daea9e7a"
},
{
"conn": "6d3ec325-4b27-4772-b0d9-36d4cc7b9e47"
}]
This does not give correct result.
I just want to know that my loop is correct?
You can use the forEach or reduce Array methods to solve this easily:
var obj= JSON.parse(...);
var connections=obj.links.reduce(function (array,elem) {
elem.connections.forEach(function (conn) {
array.push({'conn': conn});
}
return array;
},[]);

Categories