Given json like this :
{ "rss": {
"page": 1,
"results": [{
"type": "text",
"$": 10
}],
"text": [{
"content": "Lorem ipsum dolor sit amet.",
"author": {
"name": "Cesar",
"email": "cesar#evoria.com"
},
},
{
"content": "Tema Tis rolod muspi merol.",
"author": {
"name": "Cleopatre",
"email": "cleopatre#pyramid.com"
},
}]
}
In javascript, I can retrieve value like this :
var json = JSON.parse(datajson);
$.each(json.text, function(key, val) {
// this one is ok
var content = val['content'];
// this one does not work
var authorname = val['author.name'];
});
Is this a way, given the attribute name in a string format, to retrieve the value of a complex object, for instance json.text[0].author.name?
EDIT
I would like to store the needed attributes in another object like :
[
{ dt: "Text content", dd: "content" },
{ dt: "Author name", dd: "author.name"}
]
You can split your "index" by . and loop over "segments", descending through levels on each iteration.
var obj = {
author : {
name : "AuthorName"
}
}
function get_deep_index(obj, index) {
var segments = index.split('.')
var segments_len = segments.length
var currently_at = obj
for(var idx = 0; idx < segments_len; idx++) {
currently_at = currently_at[segments[idx]]
}
return currently_at
}
console.log(get_deep_index(obj, 'author.name'))
The following should fix the problem.
var authorname = val['author']['name'];
You can also store the object itself as:
var author = val['author'];
And then later on you can index the attributes from that.
console.log(author.name, author.email)
Yent give a good hint in the comments with the eval function. I resolve my needed with this kind of code:
var json = JSON.parse(myjsonasastring);
var descriptiontobeadded = [
{ dt: "Text content", dd: "content" },
{ dt: "Author name", dd: "author.name" }
];
$.each(descriptiontobeadded, function(key, val) {
var dt = '<dt>' + val.dt + '</dt>';
description.append(dt);
var dl = '<dd>' + eval('json.' + val.dd) + '</dd>';
description.append(dl);
});
Related
I am trying to loop through an array that is part of a JSON object from a page speed insights call to add all of the unused javascript Urls to a google sheet using the script editor.
Here is an example of the JSON object:
"audits": {
"unused-javascript": {
"id": "unused-javascript",
"title": "Remove unused JavaScript",
"description": "Remove unused JavaScript to reduce bytes consumed by network activity. [Learn more](https://web.dev/unused-javascript/).",
"score": 0.43,
"scoreDisplayMode": "numeric",
"numericValue": 1350,
"numericUnit": "millisecond",
"displayValue": "Potential savings of 231 KiB",
"details": {
"type": "opportunity",
"headings": [
{
"key": "url",
"valueType": "url",
"subItemsHeading": {
"key": "source",
"valueType": "code"
},
"label": "URL"
},
{
"key": "totalBytes",
"valueType": "bytes",
"subItemsHeading": {
"key": "sourceBytes"
},
"label": "Transfer Size"
},
{
"key": "wastedBytes",
"valueType": "bytes",
"subItemsHeading": {
"key": "sourceWastedBytes"
},
"label": "Potential Savings"
}
],
"items": [
{
"url": "https://connect.facebook.net/signals/config/1926350194273730?v=2.9.2=stable",
"totalBytes": 140229,
"wastedBytes": 108197,
"wastedPercent": 77.15757011763822
},
{
"url": "https://static.example.com/domain.us.modern.bundle.a02fef045566caf5d464.js",
"totalBytes": 306716,
"wastedBytes": 106243,
"wastedPercent": 34.63892414884589
},
{
"url": "https://www.googletagmanager.com/gtm.js?id=GTM-KZ",
"totalBytes": 127214,
"wastedBytes": 21845,
"wastedPercent": 17.17151000374831
}
],
"overallSavingsMs": 1350,
"overallSavingsBytes": 236285
}
},
I am attempting to loop through the "items" array within the "unused-javascript" object and get all of the urls to show in google sheets.
Here is the code I have within the script editor. When I run this, only one URL shows on the sheet. However, I am trying to get all of the URLs added to the sheet.
function pageSpeed(Url) {
var key = "AIzaSyAyHY";
var serviceUrl = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=" + Url + "&key=" + key;
var array = [];
if (key == "YOUR_API_KEY")
return "Please enter your API key to the script";
var response = UrlFetchApp.fetch(serviceUrl);
if (response.getResponseCode() == 200) {
var content = JSON.parse(response.getContentText());
if ((content != null) && (content["lighthouseResult"] != null)) {
if (content["captchaResult"]) {
var timetointeractive = content["lighthouseResult"]["audits"]["interactive"]["displayValue"].slice(0, -2);
var firstcontentfulpaint = content["lighthouseResult"]["audits"]["first-contentful-paint"]["displayValue"].slice(0, -2);
var firstmeaningfulpaint = content["lighthouseResult"]["audits"]["first-meaningful-paint"]["displayValue"].slice(0, -2);
var speedindex = content["lighthouseResult"]["audits"]["speed-index"]["displayValue"].slice(0, -2);
var unusedJs = content["lighthouseResult"]["audits"]["unused-javascript"]["details"]["items"];
for (var i = 0; i < unusedJs.items.length; i++) {
var unusedUrl;
unusedUrl = unusedJs[i]["url"]
}
}
else {
var timetointeractive = "An error occured";
var firstcontentfulpaint = "An error occured";
var firstmeaningfulpaint = "An error occured";
var speedindex = "An error occured";
var unusedJs = "An error occured";
}
}
var currentDate = new Date().toJSON().slice(0, 10).replace(/-/g, '/');
array.push([timetointeractive, firstcontentfulpaint, firstmeaningfulpaint, speedindex, currentDate, "complete", unusedUrl]);
Utilities.sleep(1000);
return array;
}
}
Any and all help is appreciated!
You're on the right track.
Take a look below at my usage of Array.prototype.map. That's the simpler route.
Your for loop would work just as well IF you declared unusedUrl outside of (ie. before) the loop AND pushed to an existing array. As it is, there's an issue of scope, so unusedUrl is redeclared on every iteration, meaning you'll only assign the last iteration's value to unusedUrl.
Both solutions are below.
Using map
var content = {
lighthouseResult: {
audits: {
'unused-javascript': {
// Other stuff
details: {
// Other stuff
items: [
{
url:
'https://connect.facebook.net/signals/config/1926350194273730?v=2.9.2=stable',
totalBytes: 140229,
wastedBytes: 108197,
wastedPercent: 77.15757011763822,
},
{
url:
'https://static.example.com/domain.us.modern.bundle.a02fef045566caf5d464.js',
totalBytes: 306716,
wastedBytes: 106243,
wastedPercent: 34.63892414884589,
},
{
url: 'https://www.googletagmanager.com/gtm.js?id=GTM-KZ',
totalBytes: 127214,
wastedBytes: 21845,
wastedPercent: 17.17151000374831,
},
],
overallSavingsMs: 1350,
overallSavingsBytes: 236285,
},
},
},
},
}
var items = content.lighthouseResult.audits['unused-javascript'].details.items
var unusedUrls = items.map(item => item.url) // OR, using es6, items.map(({ url }) => url)
console.log(unusedUrls)
Using for
var items = content.lighthouseResult.audits['unused-javascript'].details.items
var unusedUrls = []
for (var i = 0; i < items.length; i++) {
unusedUrls.push(items[i]['url'])
}
I have a list of objects. On each object I have an array.
Example:
"-KpvPH2_SDssxZ573OvM" : {
"date" : "2017-07-25T20:21:13.572Z",
"description" : "Test",
"id" : [ {
0: "0a477fed-8944-9f5d-56fd-c95fe7663a07",
1: "0a477fed-8944-9f5d-56fd-c95fe7663a08"
} ]
},
"-KpvPLSfotrZiBDeVOxU" : {
"date" : "2017-07-25T20:21:33.159Z",
"description" : "Test 2",
"id" : [ {
0: "6e79eadd-21b5-91cc-4b71-7ac1a42278b1"
} ]
}
How do I search for an object using the ID array as a parameter?
When I need to filter only one array I use filter and everything works ok.
var result = $.grep(items, function(e){ return e.id == id; });
But in this case I believe it does not work.
Thanks
Since the ID's are a little deeper in the object, and they are part of an object, I think a better approach (as compared to $.grep) would be a custom filter. Here I have assumed you want exact comparison while filtering, based on your question. But you could easily have partial comparison with indexOf as well.
var data = {
"-KpvPH2_SDssxZ573OvM": {
"date": "2017-07-25T20:21:13.572Z",
"description": "Test",
"id": [{
0: "0a477fed-8944-9f5d-56fd-c95fe7663a07",
1: "0a477fed-8944-9f5d-56fd-c95fe7663a08"
}]
},
"-KpvPLSfotrZiBDeVOxU": {
"date": "2017-07-25T20:21:33.159Z",
"description": "Test 2",
"id": [{
0: "6e79eadd-21b5-91cc-4b71-7ac1a42278b1"
}]
}
};
//console.log(data);
var inputID = "0a477fed-8944-9f5d-56fd-c95fe7663a08";
var filteredData = [];
for (var prop in data) {
if(data.hasOwnProperty(prop)) {
var item = data[prop];
var itemIDs = item.id[0];
for(var id in itemIDs) {
if (itemIDs[id] == inputID) {
filteredData.push(item);
}
}
}
}
console.log(filteredData);
I have extract a json format data from a table like this:
[ { id:"3",
"Date Extracted":"12/3",
Experiment:"normal"},
{ id:"2",
"Date Extracted":"12/3",
Experiment:"powder",
Notes:"" },
{ id:"1",
"Date Extracted":"12/3",
Experiment:"fine",
Notes:"" }
]
And I have used function like below to get only the attributes of each id like "12/3","normal", not include the name like "Date Extracted", Experiments.
Somehow this does not work.
but I have no idea how do it exactly in details.
var j = JSON.parse(data);
function(){
for(name in j.property.name)
console.log(j.property.value);
}
The extracted json data had some validation issues with the property names. You could verify your jsondata via jsonlint.com.
So the json data should likely be:
var jsonData ='[{ "id":"3", "Date Extracted":"12/3","Experiment":"normal"}, { "id":"2","Date Extracted":"12/3","Experiment":"powder","Notes":"" },{ "id":"1","Date Extracted":"12/3","Experiment":"fine","Notes":"" }]';
Function:
var json = $.parseJSON(jsonData);
$(json).each(function(i,val){
$.each(val,function(name,value){
console.log(name + " : " + value);
});
});
You can't use "for" like that.
var j = JSON.parse('[{ "id": "3", "Date Extracted": "12/3", "Experiment": "normal"}, { "id": "2", "Date Extracted": "12/3", "Experiment": "powder", "Notes": ""}, { "id": "1", "Date Extracted": "12/3", "Experiment": "fine", "Notes": ""}]');for(var i=0;i<j.length;i++){
var obj = j[i];
for(var key in obj){
var attrName = key;
var attrValue = obj[key];
console.log(attrValue);
}}
var data = [{
id: "3",
"Date Extracted": "12/3",
Experiment: "normal"
}, {
id: "2",
"Date Extracted": "12/3",
Experiment: "powder",
Notes: ""
}, {
id: "1",
"Date Extracted": "12/3",
Experiment: "fine",
Notes: ""
}];
for (var i = 0; i < data.length; i++) {
console.log("Date Extracted " + data[i]['Date Extracted'])//for index Date Extracted
console.log("Experiment " + data[i]['Experiment'])//for index Experiment
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can do using for loop like this
This question already has answers here:
How to get the difference between two arrays in JavaScript?
(84 answers)
Closed 7 years ago.
Using jQuery I would like to compare 2 objects:
sourceArray:
var origArray = [{
"Name": "Single",
"URL": "xxx",
"ID": 123
},
{
"Name": "Double",
"URL": "yyy",
"ID": 345
},
{
"Name": "Family",
"URL": "zzz",
"ID": 567
}];
destination array
var destArray = [{
"Name": "Single",
"URL": "xxx",
"ID": 123
},
{
"Name": "Double",
"URL": "yyy",
"ID": 888
},
{
"Name": "Family",
"URL": "zzz",
"ID": 567
}];
What I would like to do, is compare the target object with the source object based on the ID and find the mis-matched entries with a description on the resultant object. So the result will look like this:
var resultArray = [{
"Name": "Double",
"URL": "yyy",
"ID": 888,
"desc": "missing in source"
},
{
"Name": "Double",
"URL": "yyy",
"ID": 345,
"desc": "missing in destination"
}];
Any quick help is really appreciated.
This isn't a good use of jQuery, but here is some vanilla javascript that does what you want.
function objDiff(array1, array2) {
var resultArray = []
array2.forEach(function(destObj) {
var check = array1.some(function(origObj) {
if(origObj.ID == destObj.ID) return true
})
if(!check) {
destObj.desc = 'missing in source'
resultArray.push(destObj)
}
})
array1.forEach(function(origObj) {
var check = array2.some(function(destObj) {
if(origObj.ID == destObj.ID) return true
})
if(!check) {
origObj.desc = 'missing in destination'
resultArray.push(origObj)
}
})
return resultArray
}
https://jsfiddle.net/9gaxsLbz/1/
If you are wanting to dedupe your array, this will work:
var merged = origArray.concat(destArray);
var unique = merged.filter(function(item) {
return ~this.indexOf(item.ID) ? false : this.push(item.ID);
}, []);
Fiddle: https://jsfiddle.net/Ljzor9c6/
If you are only wanting items that were duped, you can easily invert the condition:
var merged = origArray.concat(destArray);
var dupes = merged.filter(function(item) {
return ~this.indexOf(item.ID) ? true : !this.push(item.ID);
}, []);
You can loop through the items in the first array and put the ID's in a map, then loop through the items in the second array and remove the matching ID's and add the missing.
Then just loop through the map to create the objects in the resulting array:
var origArray = [{
"Name": "Single",
"URL": "xxx",
"ID": 123
},
{
"Name": "Double",
"URL": "yyy",
"ID": 345
},
{
"Name": "Family",
"URL": "zzz",
"ID": 567
}];
var destArray = [{
"Name": "Single",
"URL": "xxx",
"ID": 123
},
{
"Name": "Double",
"URL": "yyy",
"ID": 888
},
{
"Name": "Family",
"URL": "zzz",
"ID": 567
}];
var map = {};
for (var i = 0; i < origArray.length; i++) {
map[origArray[i].ID] = 'source';
}
for (var i = 0; i < destArray.length; i++) {
var id = destArray[i].ID;
if (id in map) {
delete map[id];
} else {
map[id] = 'destination';
}
}
var resultArray = [];
for (key in map) {
var arr = map[key] == 'source' ? origArray : destArray;
for (var i = 0; arr[i].ID != key; i++) ;
resultArray.push({
Name: arr[i].Name,
URL: arr[i].URL,
ID: arr[i].ID,
desc: 'missing in ' + map[key]
});
}
// show result in StackOverflow snippet
document.write(JSON.stringify(resultArray));
var result = [];
for(var i = 0; i < oa.length; i++) {
var idx = mIndexOf(oa[i].ID);
if(idx > -1) {
oa.splice(i, 1);
da.splice(idx, 1);
}
}
for(var i = 0; i < oa.length; i++) {
var ln = result.length;
result[ln] = oa[i];
result[ln].desc = "missing in destination";
}
for(var i = 0; i < da.length; i++) {
var ln = result.length;
result[ln] = da[i];
result[ln].desc = "missing in origin";
}
function mIndexOf(id) {
for(var i = 0; i < oa.length; i++)
if(oa[i].ID == id)
return i;
return -1;
}
console.log(result);
0: Object
ID: 345
Name: "Double"
URL: "yyy"
desc: "missing in destination"
1: Object
ID: 888
Name: "Double"
URL: "yyy"
desc: "missing in origin"
jsfiddle DEMO
For things like this, you should use lodash. With lodash you can just do this:
var resultArray = _.defaults(destArray, origArray);
I am newbie to JSON, I am parsing a JSON Object and i was struck at a point where i have to read the array Elements inside a Object, that is again in another array..
Here is MY JSON
{
"DefinitionSource": "test",
"RelatedTopics": [
{
"Result": "",
"Icon": {
"URL": "https://duckduckgo.com/i/a5e4a93a.jpg"
},
"FirstURL": "xyz",
"Text": "sample."
},
{
"Result": "",
"Icon": {
"URL": "xyz"
},
"FirstURL": "xyz",
"Text": "sample."
},
{
"Topics": [
{
"Result": "",
"Icon": {
"URL": "https://duckduckgo.com/i/10d02dbf.jpg"
},
"FirstURL": "https://duckduckgo.com/Snake_Indians",
"Text": "sample"
},
{
"Result": "sample",
"Icon": {
"URL": "https://duckduckgo.com/i/1b0e4eb5.jpg"
},
"FirstURL": "www.google.com",
"Text": "xyz."
}
]
}
]
}
Here I need to read URL ,FIRSTURL and Text from RelatedTopics array and Topics array..
Can anyone help me. Thanks in advance.
Something like this
function (json) {
json.RelatedTopics.forEach(function (element) {
var url = element.Icon ? element.Icon.URL : 'no defined';
var firstURL = element.FirstURL ? element.FirstURL : 'no defined';
var text = element.Text ? element.Text : 'no defined';
alert("URL: " + url + "\nFirstURL: " + firstURL + "\nText: " + text);
if (element.Topics)
{
element.Topics.forEach(function (topicElement) {
alert("Topics - \n" + "URL: " + topicElement.Icon.URL + "\nFirstURL: " + topicElement.FirstURL + "\nText: " + topicElement.Text);
});
}
});
};
Look fiddle example
Loop through json Array like,
for(var i=0; i< RelatedTopics.length;i++){
if($.isArray(RelatedTopics[i])){
for(var j=0; j< RelatedTopics[i].Topics.length;j++){
var topics=RelatedTopics[i].Topics[j];
var text = topics.Text;
var firsturl = topics.Firsturl;
var url = topics.Icon.url;
}
}
}
if you want push it an array variable