Parsing complex object in JavaScript [duplicate] - javascript

This question already has answers here:
How to iterate over a JavaScript object?
(19 answers)
Closed 7 months ago.
I have an object as follows
{
"s": "success",
"result": {
"XX-YY-12-33": {
"quantity": "88",
"warehouse_name": "USA Hub"
},
"AD-12-Y6-00": {
"quantity": "99",
"warehouse_name": "USA Hub"
}
}
}
The result object contains multiple objects which actually is the id of an sku
I want to access this each sku but don't have them separately anywhere. Can anyone tell how can I access them?

Does this help?
I've put some comments in the code for further explanation.
const data = {
"XX-YY-12-33": {
"quantity": "88",
"warehouse_name": "USA Hub"
},
"AD-12-Y6-00": {
"quantity": "99",
"warehouse_name": "USA Hub"
}
};
// You can extract only the ids using Object.keys
const dataIds = Object.keys(data);
// Having the ref of the ids you can now iterate over them to extract the info you need per id
// Using array map function for example we can extract all the quantities:
const dataQtys = dataIds.map((id) => Number(data[id].quantity));
// alternatively you can use "Object.entries".
// If you want to sum all quantities you can use array reduce function:
const sum = dataQtys.reduce((res, qty) => res + qty, 0);
console.log('Ids: ', dataIds);
console.log('Quantities: ', dataQtys);
console.log('Sum: ' + sum);

You mean this?
Object.entries and reduce
Had you been clearer, I would have given a more complex answer first time around
const obj = {
"s": "success",
"result": {
"XX-YY-12-33": {
"quantity": "88",
"warehouse_name": "USA Hub"
},
"AD-12-Y6-00": {
"quantity": "99",
"warehouse_name": "USA Hub"
}
}
}
const res = Object.entries(obj.result)
.reduce((acc, [key,{quantity}]) => { // spread the key and extracted quantity from value
acc.keys.push(key); // save the key
acc.quantity.push(+quantity); // save the quantity (unary plus to convert to number)
acc.sum += +quantity; // sum it
return acc;
},{keys:[],quantity:[],sum:0}); // into an initialised object
console.log(res)

Related

How to extract value of a property of array of objects? [duplicate]

This question already has answers here:
Find object by id in an array of JavaScript objects
(36 answers)
Closed 5 months ago.
I have this data (data1) below, an array of objects with multiple objects inside:
[
{
"id": 35,
"code": "BP S",
"article": "BP S",
"price": 100,
"vat": null,
"status": null,
"company_id": 12
},
{
"id": 36,
"code": "B P S",
"article": "BPS",
"price": 100,
"vat": null,
"status": null,
"company_id": 12
}
]
I would like to extract the code of the first id=35.
How to do that?
My code:
import { useLocation } from "react-router-dom";
const Single = ({ inputs, title }) => {
const { state } = useLocation();
let data1 = state.foo;
console.log(data1);
You could use the High order function find to retrieve the item of the array matching the id = 35 , as in:
const item = data1.find((el)=>el.id===35)
Then you could extract the code with:
item.code
Or you could chain them:
const code = data1.find((el)=>el.id===35).code

Accessing objects in typescript and find the highest key and value of it

this.maxObj = {
"item": {
"id": 29842,
"interestName": "Pre-engagement ring",
"audienceSize": "980460",
"femaleAge18_24": "22",
"maleAge18_24": "11",
"femaleAge25_34": "25",
"maleAge25_34": "9",
"femaleAge35_44": "11",
"maleAge35_44": "2",
"femaleAge45_54": "7",
"maleAge45_54": " 1",
"femaleAge55_64": "6",
"maleAge55_64": " 1",
"femaleAge65plus": "5",
"maleAge65plus": " 0",
"gendermale": "24.6",
"genderFemale": "75.4",
"isActive": true,
"createdAt": "2021-03-22T07:01:21.000Z",
"updatedAt": "2021-03-22T07:01:21.000Z",
"deletedAt": null
},
"refIndex": 21534,
"score": 0.6113547101723916
}
Consider the above object. First, I write an "if condition" on genderMale and genderfemale to compare the values. I find genderfemale is greater. So my question is as follows: if genderFemale is greater I should select all the femaleAge (femaleAge18_24, femaleAge25_34, femaleAge35_44, femaleAge45_54,femaleAge55_64 and femaleAge65plus from the object and find the highest among it. If genderMale is greater then it should find the highest value of maleAge.
the final answer should be femaleAge25_34: "25".
Considering your object structure, you can iterate through all keys of your object by using Object.keys(). Doing so, you will be able to compare the key to any substring by using String.indexOf or something similar and add their values to an array. Finally, check everything within that array using Math.max() and you're good to go.
const items = this.maxObj.item;
let arr = [];
Object.keys(items).forEach((key) => {
if (key.includes(anySubString)) {
arr.push(items[key]);
}
});
// Adjust this one. Example is just taken from MDN
// https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Math/max
const max = arr.reduce(function(a, b) {
return Math.max(a, b);
});

how to get particular Keys Values from the exiting JSON Object in javacsript? [duplicate]

This question already has answers here:
How to get a subset of a javascript object's properties
(36 answers)
Closed 3 years ago.
I have one JSON Object and I want to create subset of JSON with particular keys values.
JSON Object
{
"Checksum": "OK",
"ID": "012B4567",
"DOB: "12-12-1991"
"Data": "Test Line 1 >>>>>↵Test Line 2 >>>>>↵Test Line 3 >>>>>",
"issue: "11-April-2015",
"DocID": "PASSPORT",
"Number: "123456789",
"Document": "PASSPORT",
"Photo": "Qk06AAAAAAAAA",
"ExpiredFlag": false,
"ExpiryDate": "01 Apr 12",
"Forename": "IMA Phoney",
"Image2": "/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ",
"ImageSource1": 0,
"Image3": "/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ",
"Image1": "/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ",
"IssueState: "USA",
"Nationality": "USA",
"PlaceOfBirth": "U.S.A",
"SecondName": "J",
"Sex": "Male",
"Surname": "XYZ"
}
I want subset from above like below:
{
"ID": "012B4567",
"Number: "123456789",
"Document": "PASSPORT",
"IssueState: "USA",
"Nationality": "USA",
"PlaceOfBirth": "U.S.A",
"SecondName": "J",
"Sex": "Male",
"Surname": "XYZ"
}
I have tried below code. It is working fine, But I am not able to understand. I need simplest way:
var data={
"CDRValidation": "CDR Validation test passed",
"AirBaudRate": "424",
"ChipID": "012B4567",
"BACStatus": "TS_SUCCESS",
"SACStatus": "TS_NOT_PERFORMED",
"Data": "Test Line 1 >>>>>\nTest Line 2 >>>>>\nTest Line 3 >>>>>",
"DocType": "PASSPORT",
"DocNumber": "123456789",
"DocID": "PASSPORT",
"Surname": "Person",
"Forename": "IMA Phoney",
"SecondName": "J",
"Nationality" : "Imaging Automation Demo State",
"Sex": "Male",
"DOB": "12 May 70",
"ExpiryDate": "01 Apr 12",
"IssueState": "Passport Agency Billerica",
"ExpiredFlag": false,
"ImageSource": 0,
"OptionalData1": "123456789123456",
"OptionalData2": "",
"DateOfIssue":"11 April 02",
"PlaceOfBirth":"Illinois, U.S.A"
}
console.log("----------------->",data);
var Fields = ({
IssueState,
ExpiryDate,
DateOfIssue,
PlaceOfBirth,
DOB,
Sex,
DocNumber,
DocType
} = data, {
IssueState,
ExpiryDate,
DateOfIssue,
PlaceOfBirth,
DOB,
Sex,
DocNumber,
DocType
})
console.log("--------subset--------->",Fields);
There are multiple ways you can handle this case. Object destructuring as you have done in your example is one simple way. You can also use an array to store the required keys and write code as below
function subset(parentObj) {
const keys = ['key1', 'key2', 'key3'];
const obj = {};
for (let i = 0, length = keys.length; i < length; i += 1) {
obj[keys[i]] = parentObj[keys[i]];
}
return obj;
}
Or you can also use the above code with some functional programming
function subset(parentObj) {
const keys = ['key1', 'key2', 'key3'];
return keys.reduce((acc, key) => ({
...acc,
[key]: parentObj[key];
}), {});
}
A simple to achieve what you are asking using ES5 is to create a list of all the properties you want to keep, and using Array#reduce add each property to a new object.
// Saves vertical space for example
var original = JSON.parse(`{"Checksum":"OK","ID":"012B4567","DOB":"12-12-1991","Data":"Test Line 1 >>>>>↵Test Line 2 >>>>>↵Test Line 3 >>>>>","issue":"11-April-2015","DocID":"PASSPORT","Number":"123456789","Document":"PASSPORT","Photo":"Qk06AAAAAAAAA","ExpiredFlag":false,"ExpiryDate":"01 Apr 12","Forename":"IMA Phoney","Image2":"/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ","ImageSource1":0,"Image3":"/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ","Image1":"/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ","IssueState":"USA","Nationality":"USA","PlaceOfBirth":"U.S.A","SecondName":"J","Sex":"Male","Surname":"XYZ"}`);
var propertiesToUse = ["ID", "Number", "Document", "IssueState", "Nationality", "PlaceOfBirth", "SecondName", "Sex", "Surname"];
var result = propertiesToUse.reduce(function(result, key) {
return result[key] = original[key], result;
}, {});
console.log(result);
What you have done is a simple way, but if you are confused with it, you can divide it into two lines and explain it.
This line actually destrucutes your object and assign the value for the mentioned keys in the object to the corresponding variables.
{
IssueState,
ExpiryDate,
DateOfIssue,
PlaceOfBirth,
DOB,
Sex,
DocNumber,
DocType
} = data
Now, each of this variable has data individually, but we want it in an object. Therefore, we use the second part, i.e. creating an object with the following variable acting as keys.
{
IssueState,
ExpiryDate,
DateOfIssue,
PlaceOfBirth,
DOB,
Sex,
DocNumber,
DocType
}
When combined you get the desired result in a single statement.

Combining values in nested objects with common properties

# Problem
Hello. I have a JSON response containing a varying amount of objects (a set of indicators), each containing a fixed set of other objects (geometries) that each contain properties (one of which is 'score').
I'm trying to gather these 'score' properties in order to later do stuff such as min/mean/max by geometry.
# Sample
Here's an example (keeping in mind there could be more than two indicators):
let data = [ {
{
"indicator": "A",
"geom": "1",
"score": 1
},
{
"indicator": "A",
"geom": "2",
"score": 2
} }, {
{
"indicator": "B",
"geom": "1",
"score": 3
},
{
"indicator": "B",
"geom": "2",
"score": 4
} } ]
# Expected result
The result I'm looking for would be something like this, with concatenated values originating from different sub-objects :
let expectedResult = {
{
"indicator": ["A", "B"],
"geom": "1",
"score": [1,3]
},
{
"indicator": ["A", "B],
"geom": "2",
"score": [2,4]
} }
# My (no good) solution
My current, ugly buggy solution is to create an array with all geom ids :
let id = data[0].map(obj => obj.geom);
Then get a complete list of all key-value :
let keyval;
data.map((indic) => { indic.map((geom) =>
{ keyval.push([car.geom, car.score])})});
And finally combine geom id var with values that have identical id (and slice off the redundant id) :
id.map((geom, idx) => {keyval.map((arr) => {
if (car === arr[0]) { id.push(geom, arr.splice(0,1)})
}
})
});
Would anyone know of a more elegant/efficient.. and more importantly working solution ? During my research saw a lot of Array.prototype.reduce(), but didn't figure out how to use it in such a nested configuration.
Thanks,
O.
Use Array#reduce to collect the values into a Map, then use Map#values, and the spread syntax to convert back to an array:
const data = [[{"indicator":"A","geom":"1","score":1},{"indicator":"A","geom":"2","score":2}],[{"indicator":"B","geom":"1","score":3},{"indicator":"B","geom":"2","score":4}]];
const result = [...[].concat(...data).reduce((map, o) => {
const item = map.get(o.geom) || { geom: o.geom, indicator: [], score: [] }; // get the item from the map, or create a new one
item.indicator.push(o.indicator);
item.score.push(o.score);
return map.set(o.geom, item); // set the item and return the map reference
}, new Map).values()]; // get the map values iterator, and use spread (...) to get an array
console.log(result);

Count no. of entries in a json object having specific values in multiple keys

Is there a way to fetch/search data from a json object, similar to firing a query, using javascript?
My scenario: I have a big json object (if you think of it like a database, it has 12 columns, and 1000 rows). I need to know how many rows have a specific value pair (i.e. number of rows having , 'USA' in column 1 and 'INDIA' in column 2).
Eg.(For example, I have created a small example json object)
json object:
{"export":
[{"goods":"Wheat ", "from":"GHANA", "to":"AUSTRALIA"},
{"goods":"Wheat", "from":"USA", "to":"INDIA"},
{"goods":"Wheat", "from":"SINGAPORE", "to":"MALAYSIA"},
{"goods":"Wheat", "from":"USA", "to":"INDIA"},
]}
In the example, since there are two rows where from is USA and to is INDIA.
It can be thought of similar to mysql query:
select * from export where from = "USA" and to = "INDIA";
Can I do this on a json object using javascript ?
If not, can a similar thing be done from a csv file, I also have the csv file of that data?
Yes, just filter the array to get the elements meeting your query, and count the length of what's left. Here's the code in a re-usuable functional form
function counter(f, t) {
return json.export.filter(function(elem) {
return elem.from===f && elem.to===t;
}).length;
}
You can use filter to code an expression that will match more than one criteria:
o.export.filter(function(a){return a.from=="USA" && a.to=="INDIA"}).length
I like re-usable filter callbacks, which would let you change criteria at call time instead of code time:
function match(x){ return x[this[0]]===this[1]; }
//usage:
o.export.filter(match,["from", "USA"]).filter(match, ["to","INDIA"]).length;
the re-usable ones lets you set different columns and compare values without rewriting the function.
This should work:
var a = {"export":
[{"goods":"Wheat ", "from":"GHANA", "to":"AUSTRALIA"},
{"goods":"Wheat", "from":"USA", "to":"INDIA"},
{"goods":"Wheat", "from":"SINGAPORE", "to":"MALAYSIA"},
{"goods":"Wheat", "from":"USA", "to":"INDIA"},
]};
var b = 0;
for(var i = 0; i < a.export.length; i++){
if( a.export[i].from == 'USA' && a.export[i].to == 'INDIA'){
b++;
}
}
You can use filter() and length property. filter() will filter array based on our condition, for getting array count use length property.
var data = {
"export": [{
"goods": "Wheat ",
"from": "GHANA",
"to": "AUSTRALIA"
}, {
"goods": "Wheat",
"from": "USA",
"to": "INDIA"
}, {
"goods": "Wheat",
"from": "SINGAPORE",
"to": "MALAYSIA"
}, {
"goods": "Wheat",
"from": "USA",
"to": "INDIA"
}, ]
};
var count = data.export.filter(function( v) {
return v.from == 'USA' && v.to == 'INDIA'
}).length;
alert(count);
This is a more detailed example for a structured query of structured data, with a bonus for sorting the result array.
It features a small function select(from, where, sort) with three parameters.
from: The data source as array, required.
where: An object with one ore more key/value pairs, if more than one is supplied, the conditions are with and chained. The parameter is ommitted if falsy.
sort: An array with key/value pair objects which sortes the result set with the key ascending with value 1, descending with value -1. The sort features a string sort. The parameter is ommitted if falsy.
The test case returns:
Count of all sets with from = 'USA' and to = 'INDIA'.
All sets with from = 'USA' and to = 'INDIA', not sorted.
All sets sorted by from ascending.
var data = {
"export": [
{ "goods": "Wheat ", "from": "GHANA", "to": "AUSTRALIA" },
{ "goods": "Wheat", "from": "USA", "to": "INDIA" },
{ "goods": "Wheat", "from": "SINGAPORE", "to": "MALAYSIA" },
{ "goods": "Wheat", "from": "USA", "to": "INDIA" }
]
};
function select(from, where, sort) {
var data = from.slice(0);
where && Object.keys(where).forEach(function (k) {
data = data.filter(function (d) {
return d[k] === where[k];
});
});
sort && data.sort(function (a, b) {
var value = 0;
sort.some(function (el) {
var key = Object.keys(el)[0];
value = ~el[key] ? a[key].localeCompare(b[key]) : b[key].localeCompare(a[key]);
return value;
});
return value;
});
return data;
}
function print(o) {
document.body.innerHTML += '<pre>' + JSON.stringify(o, 0, 4) + '</pre>';
}
print(select(data.export, { from: 'USA', to: 'INDIA' }).length);
print(select(data.export, { from: 'USA', to: 'INDIA' }));
print(select(data.export, {}, [{ from: 1 }]));

Categories

Resources