how to change the structure of the output - javascript

This is the start of the object. I should be able to get the elements of celldata.values.
var generatedObj1 = {
"agg": "Glossar",
"ifa": null,
"ifv": null,
"ird": null,
"afv": null,
"ard": null,
"metaData": {
"cellMetaDataList": [{
"cell": "glossar", // <-- cell type
"cmv": null,
"crd": null,
"logicalData": {
"body": [{
"id": "f5d", // <-- body id 1
"name": "name", // <-- attribute name 1
"minLength": 3,
"maxLength": 100,
"minValue": null,
"maxValue": null,
"wertebereich": "ALPHANUMERISCH",
"validationCode": "",
"exampleValues": ["Langer Name", "Kurzer Name", "Kein Name"]
},
{
"id": "42", // <-- body id 2
"name": "kurzname", // <-- attribute name 2
"minLength": 3,
"maxLength": 20,
"minValue": null,
"maxValue": null,
"wertebereich": "ALPHANUMERISCH",
"validationCode": "",
"exampleValues": ["long_desc", "short_desc", "no_desc"]
},
{
"id": "9d", // <-- body id 3
"name": "eindeutig", // <-- attribute name 3
"minLength": 1,
"maxLength": 1,
"minValue": null,
"maxValue": null,
"wertebereich": "WAHRHEITSWERT",
"validationCode": "",
"exampleValues": [true, false]
}
]
}
}]
},
"data": {
"cellData": [{ // row 1 from res1
"cell": "glossar", // <-- cell type
"id": "5b", // <- UUID v4 (generated by the function)
"cmv": null,
"crd": null,
"caption": {
"pers": "string",
"custNr": "string",
"fnam": "string",
"snam": "string",
"sysId": "string"
},
"values": [{
"name": "name", // <-- attribute name 1
"value": "Langer Name",
"bodyRefId": "5d" // <-- body id 1
},
{
"name": "kurzname", // <-- attribute name 2
"value": "no_desc",
"bodyRefId": "42" // <-- body id 2
},
{
"name": "eindeutig", // <-- attribute name 3
"value": false,
"bodyRefId": "9d" // <-- body id 3
}
]
},
{ // row 2 from res1
"cell": "glossar", // <-- cell type
"id": "5c", // <- UUID v4 (generated by the function)
"cmv": null,
"crd": null,
"caption": {
"pers": "string",
"custNr": "string",
"fnam": "string",
"snam": "string",
"sysId": "string"
},
"values": [{
"name": "name", // <-- attribute name 1
"value": "Kein Name",
"bodyRefId": "5d" // <-- body id 1
},
{
"name": "kurzname", // <-- attribute name 2
"value": "short_desc",
"bodyRefId": "42" // <-- body id 2
},
{
"name": "eindeutig", // <-- attribute name 3
"value": true,
"bodyRefId": "9d" // <-- body id 3
}
]
},
{ // row 3 from res1
"cell": "glossar", // <-- cell type
"id": "5d", // <- UUID v4 (generated by the function)
"cmv": null,
"crd": null,
"caption": {
"pers": "string",
"custNr": "string",
"fnam": "string",
"snam": "string",
"sysId": "string"
},
"values": [{
"name": "name", // <-- attribute name 1
"value": "Kurzer Name",
"bodyRefId": "5d" // <-- body id 1
},
{
"name": "kurzname", // <-- attribute name 2
"value": "short_desc",
"bodyRefId": "42" // <-- body id 2
},
{
"name": "eindeutig", // <-- attribute name 3
"value": true,
"bodyRefId": "9d" // <-- body id 3
}
]
}
]
}
}
Blockquote
the returned array should be converted to match the metadata.
Each entry in the array describes an object in the result object.
and should be able to change implement the requirement in the function below.
function add(input1) {
let exampleValues1 = input1.metaData.cellMetaDataList[0].logicalData.body.map(({
exampleValues
}) => exampleValues);
return comb(exampleValues1,20);
}
the combination function .
function comb(args,output) {
var combination = [], max = args.length-1;
function helper(arr, i) {
for (var j=0, l=args[i].length; j<l; j++) {
var a = arr.slice(0); // clone arr
a.push(args[i][j]);
if (i==max)
combination.push(a);
else
helper(a, i+1);
}
}
helper([], 0);
while(combination.length < output){
combination = combination.concat(combination)}
return combination.sort(function() {
return .5 - Math.random();
}).slice(0,output); }
console.log(add(generatedObj1));
Sample result:
[["Langer Name", "no_desc", false],
["Kein Name", "short_desc", true]
["Kurzer Name", "short_desc", true]
];
the returned array should be converted to match the metadata.
Each entry in the array describes an object in the result object.
You can still just call the add function and get your input with it
The input does not change at all we are just changing the output... (that's why the ticket is named adaptation of the output structure)
For every string artay within the output of the comb function the add function should create one object within the cellData element. It should have cell type, an id, a null cmv and crd value, as well es the caption object
Most importantly it should have an values array having an object withe the name of the attribute (from body.name) the value (from the array comb returned) and a bodyRefId (from body.id)
How can I implement this in my function add()?

You can create an object from an array by filling the fields of the object using the Square brackets notation. The method would look like this:
function mapArrayToObject(cellDataValues) {
const obj = {};
cellDataValues.forEach(element => {
const fieldName = element[0];
const fieldValue = element[2];
obj[fieldName] = fieldValue;
});
return obj;
}
Update 09/17/2020 (The question was misunderstood)
After studying your question carefully I guess that your objective is the next one: After the execution of the add function what you want to get is an object with some fields (id, cell, caption...) and a values field that contains the values computed by the comb function, but parsed into objects that contains information about the body.
In order to achieve it I purpose a solution divided in 3 steps inside the add function:
Create an object with all the fields that are not related to the values computed by the comb function.
Execute the comb function.
Iterate through the values obtained, using the object created at step one as a template (cloning it) and use the index of the value you are iterating through to know which body you are pointing to in order to obtain the name and bodyRefId for each value.
The implementation would be:
function add(input1) {
// FIRST STEP: Creating the template object
const metaData = input1.metaData.cellMetaDataList[0];
const bodies = metaData.logicalData.body;
let emptyObj = {
id: "ID GENERATED BY THE FUNCTION",
cell: metaData.cell,
cmv: null,
crd: null,
caption: {
"pers": "string",
"custNr": "string",
"fnam": "string",
"snam": "string",
"sysId": "string"
}
};
// SECOND STEP: Calling to the comb function
let exampleValues1 = bodies.map(({ exampleValues }) => exampleValues);
const valuesArr = comb(exampleValues1,20);
// THIRD STEP: Parsing (Tricky part)
// Iterating through each collection of values -> [], [], []
const valuesObj = valuesArr.map(arr => {
// Cloning the template object
const obj = { ...emptyObj };
// Iterating through each value -> 'val1', 'val2', 'val3'
const valuesArr = arr.map((value, index) => {
// Using the index in order to know the body.
// For example, when index is 0 we know that we can get the name from bodies[0]
return {
name: bodies[index].name,
value: value,
bodyRefId: bodies[index].id
}
})
// Assigning the parsed values to the cloned template object
obj.values = valuesArr;
// Returning the object as we are using the map function
return obj;
});
// Now, valuesObj should have the expected structure
return valuesObj;
}

Related

Find an object and its parent by a property value of a nested object with Javascript

Given the following sample JSON (stringified from the corresponding JavaScript object), I need to extract this information:
Find the object in persons which has the reference = 2.
If a person with this reference was found, get the name of the person's parent element (here: "B").
In the end, I need to build a new object looking similar to this. This won't be problematic but I'm struggling with how to extract these objects from the source. I tried different approaches with find(), map(), flatMap() and filter() but none of them really worked.
{
companyName: "B",
person: {
"reference": 2,
"name": "Bob"
}
}
Source
{
"root": [
{
"companies": [
{
"name": "A",
"persons": [
{
"reference": 1,
"name": "Alex"
}
]
}
]
},
{
"companies": [
{
"name": "B",
"persons": [
{
"reference": 2,
"name": "Bob"
},
{
"reference": 3,
"name": "Charles"
}
]
}
]
}
]
}
If you're just interested in the name of the company you can find it using:
const reference = 2;
const company = data.root.flatMap(item => item.companies)
.find(company => company.persons.some(person => person.reference === reference));
const companyName = company?.name;
// or if you cannot use optional chaining
const companyName = (company || {}).name;
In data.root.flatMap(item => item.companies) we iterate through all items in root, for each item we select its companies property. Since we don't want a nested array we use flatMap() to flatten the result by 1 level. This leaves us with an array of companies.
After that we'll call find() on the companies array, since we are looking for a specific company name. The criteria of the company is that some() (1 or more) of the persons should match the provided reference. If no match is found null will be returned (from find()).
We then take the find() result (company) and navigate to the name via optional chaining ?.. This will return the name of the company if present, or undefined if company is null
You can use array.reduce here
let data = JSON.parse(`{
"root": [
{
"companies": [
{
"name": "A",
"persons": [
{
"reference": 1,
"name": "Alex"
}
]
}
]
},
{
"companies": [
{
"name": "B",
"persons": [
{
"reference": 2,
"name": "Bob"
},
{
"reference": 3,
"name": "Charles"
}
]
}
]
}
]
}`)
// GET ALL THE COMPANIES DATA
let companies = data.root.reduce(
(prevValue, currValue) => {
prevValue.push(...currValue.companies)
return prevValue
},
[]
)
// FIND AND CREATE EXPECTED RESULT SET
let results = companies.reduce(
(prevValue, currValue) => {
// loop inside a loop, mind it
let refPerson = currValue.persons.find((item)=> item.reference == 2)
if(refPerson){
prevValue.push({
companyName: currValue.name,
person: refPerson
})
}
return prevValue
},
[]
)
console.log(results)

How parse JSON with complex nesting and unnamed array?

I am trying to figure out how to parse the JSON response I receive when I make a call to a specific database (JSON response shown below) using vanilla javascript - and so far I have not had any luck. I am placing an API call to the Quickbase database and they have a standard formatting for their JSON response. The API i am calling can be found at this link: https://developer.quickbase.com/operation/runQuery.
Here is what a response from the API call looks like
{
"data": [
{
"6": {
"value": 11.0
},
"69": {
"value": "A"
},
"70": {
"value": "B"
}
},
{
"6": {
"value": 11.0
},
"69": {
"value": "C"
},
"70": {
"value": "D"
}
}
],
"fields": [
{
"id": 6,
"label": "Related Invoice",
"type": "numeric"
},
{
"id": 69,
"label": "TEST1",
"type": "text"
},
{
"id": 70,
"label": "TEST2",
"type": "text"
}
],
"metadata": {
"numFields": 3,
"numRecords": 2,
"skip": 0,
"totalRecords": 2
}
}
And this is what I want to parse it into (do NOT need to omit the JSON not shown here - I just did that for clarity)
{
"data": [
{
"Related Invoice":11.0,
"TEST1":"A",
"TEST2":"B"
},
{
"Related Invoice":11.0,
"TEST1":"C",
"TEST2":"D"
}
]
}
Below is the full javascript code i am using
let headers = {
'QB-Realm-Hostname': 'XXXXXX',
'User-Agent': 'Invoice',
'Authorization': 'XXXXXX',
'Content-Type': 'application/json'
}
let body =
{
"from": "bq2paydp2",
"select": [
6,
69,
70
],
"where": "{6.EX.11}",
"sortBy": [
{
"fieldId": 6,
"order": "ASC"
},
{
"fieldId": 69,
"order": "ASC"
}
]
}
const xmlHttp = new XMLHttpRequest();
xmlHttp.open('POST', 'https://api.quickbase.com/v1/records/query', true);
for (const key in headers) {
xmlHttp.setRequestHeader(key, headers[key]);
}
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState === XMLHttpRequest.DONE) {
console.log(xmlHttp.responseText);
let line_items = JSON.parse(this.responseText, dataReviver);
console.log(line_items);
//function dataReviver (key, value) {
//if (key = 6)
// {
// var newHeaderName = 99;
// return newHeaderName;
// }
//
// return value;
//}
//document.getElementById('abc').innerHTML = line_items.data[0][6].value;
function generateTableHead(table,tableData) {
let thead = table.createTHead();
let row = thead.insertRow();
for (let key of tableData) {
let th = document.createElement("th");
let text = document.createTextNode(key);
th.appendChild(text);
row.appendChild(th);
}
};
function generateTable(table, tableData) {
for (let element of tableData) {
let row = table.insertRow();
for (key in element) {
let cell = row.insertCell();
let text = document.createTextNode(element[key]);
cell.appendChild(text);
}
}
};
let table = document.querySelector("table");
let tableData = Object.keys(line_items.data[0]);
generateTableHead(table, tableData);
generateTable(table, line_items.data);
}
};
xmlHttp.send(JSON.stringify(body));
This is what I am trying to achieve
|-----------------------------------------|
| Count | Related Invoice | TEST1 | TEST2 |
|-------|-----------------|-------|-------|
| 1 | 11.0 | A | B |
|-------|-----------------|-------|-------|
| 2 | 11.0 | C | D |
|-----------------------------------------|
I need to accomplish 3 things:
#1 Rename "6", "69 and "70" to the corresponding fields.label ( "Related Invoice", "TEST1" and "TEST2" ).
#2 Take the value of the objects nested under the objects shown above in #1 ( 11.0, "A", "B", ... ) and set them as the value of the objects shown in #1 above. This would, for example, make 6 (Related Invoice) the key and 11.0 the value.
#3 I ultimately want to display this in a table on a webpage. the html and css I can handle its the Javascript and JSON that I am not that great with.
If you need me to clarify anymore information please let me know.
To transform the data in the way you're looking, you'll need to loop over the data key in the object and create a new array based on the result of the loop.
A way to do this is with Array.prototype.map(). With this you can loop over each item in the array and return a new value.
In this map loop you are looping over each item in the data array. For each item you'll want to get the id and label from the fields array and use that array to create a new object. To create a new object within in a loop, you could use the Array.prototype.reduce() method.
So in this case you'll have a nested loop. The inner loop will loop over the fields array and uses the id to get the correct value from data array. It then returns an object with the label and the value set like you requested. The surrounding map method will then return a new array with objects. Tadaa, magic!
const response = {
"data": [{
"6": {
"value": 11.0
},
"69": {
"value": "A"
},
"70": {
"value": "B"
}
},
{
"6": {
"value": 11.0
},
"69": {
"value": "C"
},
"70": {
"value": "D"
}
}
],
"fields": [{
"id": 6,
"label": "Related Invoice",
"type": "numeric"
},
{
"id": 69,
"label": "TEST1",
"type": "text"
},
{
"id": 70,
"label": "TEST2",
"type": "text"
}
],
"metadata": {
"numFields": 3,
"numRecords": 2,
"skip": 0,
"totalRecords": 2
}
};
const transformResponseData = (response) => {
const { data, fields } = response;
// Return a new array with objects based on the values
// of the data and fields arrays.
const revivedData = data.map(entry =>
fields.reduce((object, { id, label }) => {
object[label] = entry[id].value;
return object;
}, {})
);
// Combine the original object with the new data key.
return {
...response,
data: revivedData
};
};
const createTable = ({ data, fields }) => {
const table = document.createElement('table');
const tHead = table.createTHead();
const tBody = table.createTBody();
const tHeadRow = tHead.insertRow();
// Create the counts cell manually.
const tHeadRowCountCell = document.createElement('th');
tHeadRowCountCell.textContent = 'Count';
tHeadRow.append(tHeadRowCountCell);
// Create a head for each label in the fields array.
for (const { label } of fields) {
const tHeadRowCell = document.createElement('th');
tHeadRowCell.textContent = label;
tHeadRow.append(tHeadRowCell);
}
// Output all the values of the new data array.
for (const [index, entry] of data.entries()) {
const tBodyRow = tBody.insertRow();
// Create a new array with the index and the
// values from the object.
const values = [
index + 1,
...Object.values(entry)
];
// Loop over the combined values array.
for (const [index, value] of values.entries()) {
const tBodyCell = tBodyRow.insertCell();
tBodyCell.textContent = index === 1 ?
value.toFixed(1) :
value;
}
}
return table;
};
const data = transformResponseData(response);
const table = createTable(data);
document.body.append(table);

Look up value from array in another array, and then match a second value Google Apps Script Javascript JSON API

I'm importing data from my crm Pipedrive into Google sheets using Google Apps Script. This is part of a larger process but I'm at an impasse with this section of the script. I need to return a value by matching two parts of one array to another array.
First I pull all deal fields, which returns custom field keys and their id/label pairs. Here's a simplified output example:
{
"success": true,
"data": [
{
"id": 12500,
"key": "c4ecbe01c34994ede3a50c0f8",
"name": "Lead Type",
"options": [
{
"label": "Expired",
"id": 28
},
{
"label": "Sale",
"id": 29
},
{
"label": "Rent",
"id": 30
},
{
"label": "Other",
"id": 31
}
],
"mandatory_flag": false
}
]
}
Then I have separate info from a specific deal that includes an id. I need to match the below id 28 to the above array and return the label Expired:
var leadType = dealresponse.data["c4ecbe01c34994ede3a50c0f8"];
which returns 28
I don't know what '28' means so that's why I need to match it to the label Expired.
The dealFields array is long, maybe 50 or 100 of the above array objects. And there are around 10 custom deal field keys where I will have to return the label base on matching the key and id. I think I have to loop each key and id to return the label. But not sure of the optimum way to do this and save on processing power.
I tried:
for (var i in dealFieldsresponse) {
if (dealFieldsresponse[i].data.key == "c4ecbe01c34994ede3a50c0f8") {
for (var j in dealFieldsresponse[j]) {
if (dealFieldsresponse[j].id == "28") {
Logger.log(dealFieldsresponse[j].label);
}
}
}
}
It's not working. I'm new at javascript and programming in general so this is my best guess and I appreciate any insights.
Edit: here's a bigger chunk of code that I have to work with:
// Get deal fields data
var dealFieldsurl = URL +'/v1/dealFields?api_token='+ API_TOKEN;
var options = {
"method": "get",
"contentType": "application/json",
};
var dealFieldsresponse = UrlFetchApp.fetch(dealFieldsurl, options);
dealFieldsresponse = JSON.parse(dealFieldsresponse.getContentText());
// Get deal data
var dealurl = URL +'/v1/deals/' + dealId + '?api_token='+ API_TOKEN;
var options = {
"method": "get",
"contentType": "application/json",
};
var dealresponse = UrlFetchApp.fetch(dealurl, options);
dealresponse = JSON.parse(dealresponse.getContentText());
var propertyAddress = dealresponse.data["9bd1d8c4f07f5795fd8bffb16f3b63c6547d7d3a"];
var leadType = dealresponse.data["c4ecbe01c3494d1be52432f4a3194ede3a50c0f8"];
var dealType = dealresponse.data["a4269fb4730cf7fd1787752be94eacbc4b0de24e"];
var dealSource = dealresponse.data["d76fa2d6f8454a51f7d64d981cd9320877bc2ea0"];
var marketingFor = dealresponse.data["58cb55090b55652b7f89a8b44074682d874c548a"];
var dateListedOnMarket = dealresponse.data["aa49c7b95a7d151bec4c2d936f6ab40d0caea43c"];
var dateTakenOffMarket = dealresponse.data["660c1250b0a641a10ff9121c2df124ff89c13052"];
var askingPrice = dealresponse.data["1de94dbf589fda7a3a3248662cd24f03d512a961"];
And the dealFieldsresponse variable stores an array with many objects containing arrays. Here are two primary objects, as you can see each has a key and then options. I need to match the key and then find the id within options for each key
{
"id": 12500,
"key": "c4ecbe01c3494d1be52432f4a3194ede3a50c0f8",
"name": "Lead Type",
"order_nr": 64,
"field_type": "set",
"add_time": "2020-08-20 19:33:22",
"update_time": "2020-08-20 19:33:22",
"last_updated_by_user_id": 11678191,
"active_flag": true,
"edit_flag": true,
"index_visible_flag": true,
"details_visible_flag": true,
"add_visible_flag": true,
"important_flag": true,
"bulk_edit_allowed": true,
"searchable_flag": false,
"filtering_allowed": true,
"sortable_flag": true,
"options": [
{
"label": "Expired",
"id": 28
},
{
"label": "Sale",
"id": 29
},
{
"label": "Rent",
"id": 30
},
{
"label": "Other",
"id": 31
}
],
"mandatory_flag": false
},
{
"id": 12502,
"key": "a4269fb4730cf7fd1787752be94eacbc4b0de24e",
"name": "Deal Type",
"order_nr": 65,
"field_type": "set",
"add_time": "2020-08-20 19:57:12",
"update_time": "2020-08-20 19:57:12",
"last_updated_by_user_id": 11678191,
"active_flag": true,
"edit_flag": true,
"index_visible_flag": true,
"details_visible_flag": true,
"add_visible_flag": true,
"important_flag": true,
"bulk_edit_allowed": true,
"searchable_flag": false,
"filtering_allowed": true,
"sortable_flag": true,
"options": [
{
"label": "Lease",
"id": 37
},
{
"label": "Financing",
"id": 38
},
{
"label": "Assign",
"id": 39
},
{
"label": "ST",
"id": 40
},
{
"label": "Other (see notes)",
"id": 41
}
],
"mandatory_flag": false
},
Edit 2: how do I return the labels for multiple ids?
const obj = {
"a4269fb4730cf7fd1787752be94eacbc4b0de24e": {id: 37,38}, "58cb55090b55652b7f89a8b44074682d874c548a": {id: 44,45},
"2ec54cce0d091b69b1fd1a245c7aad02b57cadb8": {id: 126},
"fab84c732295022ecd7bdf58892a62cb4d8ecf24": {id: 50,52,54},
};
For example, I'd want the first to return red, blue as a string, and the second to return green, orange as a string. Assuming the labels that match the ids are colors. The third one only has one id, but the fourth one has three. How do I account for this? And I'd like my output to be some kind of array where I can then say search key a4269fb4730cf7fd1787752be94eacbc4b0de24e and return value red, blue as a string
I believe your goal as follows.
You want to retrieve the value of label using key and id from the JSON object in your question using Google Apps Script.
As a sample situation, you want to retrieve the value of "label": "Expired" using "key": "c4ecbe01c34994ede3a50c0f8" and "id": 28.
The JSON object has the arrays of data and options. Both arrays have the several elements.
Modification points:
If dealFieldsresponse is the JSON object in your question, dealFieldsresponse.data and dealFieldsresponse.data[].options are 1 dimensional array. When you want to retrieve the value of key and id, it is required to loop those arrays.
When above points are reflected to your script, it becomes as follows.
Modified script:
const searchKey = "c4ecbe01c34994ede3a50c0f8"; // Please set the value of key.
const searchId = 28; // Please set the value of id.
const dealFieldsresponse = {
"success": true,
"data": [
{
"id": 12500,
"key": "c4ecbe01c34994ede3a50c0f8",
"name": "Lead Type",
"options": [
{
"label": "Expired",
"id": 28
},
{
"label": "FSBO",
"id": 29
},
{
"label": "FRBO",
"id": 30
},
{
"label": "Other",
"id": 31
}
],
"mandatory_flag": false
}
]
};
const data = dealFieldsresponse.data;
for (let i = 0; i < data.length; i++) {
if (data[i].key == searchKey) {
const options = data[i].options;
for (let j = 0; j < options.length; j++) {
if (options[j].id.toString() == searchId.toString()) {
// Logger.log(options[j].label);
console.log(options[j].label);
}
}
}
}
Other sample:
As other sample script, how about the following script? In this sample, the result values are put in an array.
const searchKey = "c4ecbe01c34994ede3a50c0f8"; // Please set the value of key.
const searchId = 28; // Please set the value of id.
const dealFieldsresponse = {
"success": true,
"data": [
{
"id": 12500,
"key": "c4ecbe01c34994ede3a50c0f8",
"name": "Lead Type",
"options": [
{
"label": "Expired",
"id": 28
},
{
"label": "FSBO",
"id": 29
},
{
"label": "FRBO",
"id": 30
},
{
"label": "Other",
"id": 31
}
],
"mandatory_flag": false
}
]
};
const res = dealFieldsresponse.data.reduce((ar, {key, options}) => {
if (key == searchKey) {
options.forEach(({id, label}) => {
if (id == searchId) ar.push(label);
});
}
return ar;
}, []);
console.log(res)
Added:
When you want to retrieve the multiple values using the multiple key and id, how about the following sample script? In this sample script, the key c4ecbe01c34994ede3a50c0f8 and id 28 and the key a4269fb4730cf7fd1787752be94eacbc4b0de24e and id 37 are searched and the values of label are retrieved.
const obj = {
"c4ecbe01c34994ede3a50c0f8": {id: 28},
"a4269fb4730cf7fd1787752be94eacbc4b0de24e": {id: 37}
}; // Please set the key and id you want to search.
const dealFieldsresponse = {
"success": true,
"data": [
{
"id": 12500,
"key": "c4ecbe01c34994ede3a50c0f8",
"name": "Lead Type",
"options": [
{
"label": "Expired",
"id": 28
},
{
"label": "FSBO",
"id": 29
},
{
"label": "FRBO",
"id": 30
},
{
"label": "Other",
"id": 31
}
],
"mandatory_flag": false
}
]
};
dealFieldsresponse.data.forEach(({key, options}) => {
if (obj[key]) {
options.forEach(({id, label}) => {
if (id == obj[key].id) obj[key].label = label;
});
}
});
console.log(obj)
Result:
When above script is run, the following result is obtained.
{
"c4ecbe01c34994ede3a50c0f8":{"id":28,"label":"Expired"},
"a4269fb4730cf7fd1787752be94eacbc4b0de24e":{"id":37}
}
At above sample JSON object, the label of the key c4ecbe01c34994ede3a50c0f8 and id 28 is retrieved.

Array element comparison with Json response in Javascript

I have a Json response which looks like this.
[
{
"name": "name1",
"id": "1"
},
{
"name": "name2",
"id": "2"
},
{
"name": "name4",
"id": "4"
},
{
"name": "name5",
"id": "5"
}
]
I have another array called "a" which has only id [1,2,3,4,5]. Now i have to compare every element in the array with json response object id. For example, the first element of array "a" exists in json response object , then its respective name should be retrieved and stored in another new array called "b" -> [name1]. The second element of array "a" exists in json response object , then its respective name should be retrieved and appended in "b" array -> [name1,name2]. The third element of array "a" does not exists in json response object , hence no name. In this case, Instead of name, "0" should be appedned in b array for that id -> [name1,name2,0]. The fourth element of array "a" exists in json response object , then its respective name should be retrieved and appended in b array -> [name1,name2,0,name4]. The fifth element of array "a" exists in json response object , then its respective name should be retrieved and appended in b array -> [name1,name2,0,name4,name5].
I tried to implement this by the following code. But instead of [name1,name2,0,name4,name5] , I am getting [name1,name2,name4,name5,0]
for (var i = 0; i < a.length; i++) {
if (a.includes(jsonResponse[i].id)) {
b.push(jsonResponse[i].name);
}
else{
b.push("0");
}
}
You need to search for each element of b in the entire jsonResponse array, not just test the current index of jsonResponse.
Use .find() to find the element with the ID you're looking for.
let jsonResponse = [{
"name": "name1",
"id": "1"
},
{
"name": "name2",
"id": "2"
},
{
"name": "name4",
"id": "4"
},
{
"name": "name5",
"id": "5"
}
];
let a = [1, 2, 3, 4, 5];
let b = a.map(id => {
let found = jsonResponse.find(u => u.id == id);
return found ? found.name : "0";
});
console.log(b);
You can use Map collection to have O(1) while accessing to the desired element when you map your elements:
let mapResponse = new Map(jsonResponse.map(s=> [+s.id, s.name]));
const result = a.map(id => mapResponse.get(id) || '0')
An example:
let jsonResponse = [
{
"name": "name1",
"id": "1"
},
{
"name": "name2",
"id": "2"
},
{
"name": "name4",
"id": "4"
},
{
"name": "name5",
"id": "5"
}
];
let a = [1, 2, 3, 4, 5];
let mapResponse = new Map(jsonResponse.map(s=> [+s.id, s.name]));
const result = a.map(id => mapResponse.get(id) || '0')
console.log(result);

cannot update an array of elements via a 2d iteration

I have two arrays of object, the first array (printerChart, around 80 elements) is made of the following type of objects:
[{
printerBrand: 'Mutoh',
printerModel: 'VJ 1204G',
headsBrand: 'Epson',
headType: '',
compatibilty: [
'EDX',
'DT8',
'DT8-Pro',
'ECH',
],
},
....
]
The second array (items, around 500 elements) is made of the following type of objects:
[
{
"customData": {
"brand": {
"value": {
"type": "string",
"content": "hp"
},
"key": "brand"
},
"printer": {
"value": {
"type": "string",
"content": "c4280"
},
"key": "printer"
}
},
"name": "DT8 XLXL",
"image": {
"id": "zLaDHrgbarhFSnXAK",
"url": "https://xxxxxxx.net/images/xxxxxx.jpg"
},
"brandId": "xxxxx",
"companyId": "xxxx",
"createdAt": "2018-03-26T14:39:47.326Z",
"updatedAt": "2018-04-09T14:31:38.169Z",
"points": 60,
"id": "dq2Zezwm4nHr8FhEN"
},
...
]
What I want to do is to iterate via the second array and, if the part of the name of an item (i.e. DT8) is included in an element of the array 'compatibility' of the first array, I would like to include a new properties to it from the element of the first array: printerBrand. I have tried but somehow the iteration doesn't take place correctly. This is what I tried:
items.forEach((item) => {
printerChart.forEach((printer) => {
if (printer.compatibilty.some(compatibleElem => (
item.name.includes(compatibleElem)))) {
item.printerBrand = printer.printerBrand;
} else {
item.printerBrand = '';
}
});
});
What am I doing wrong?
You do
items.items.forEach(...)
Shouldn't you be doing
items.forEach(...)
?
I suggest to initialize item.printerBrand with an empty string and use a nested approach of some for getting a brand and to exit the loops, if found.
This prevents to get an empty string even if there is a brand to assign.
items.forEach((item) => {
item.printerBrand = '';
printerChart.some(printer => {
if (printer.compatibilty.some(compatibleElem => item.name.includes(compatibleElem))) {
item.printerBrand = printer.printerBrand;
return true;
}
});
});

Categories

Resources