I've been trying to loop through a mulitnested json object but everytime it displays undefined. I've wanted to display playcount and the name of the song. I plan on using this with a bar chart.
I tried this expecting ['playcount', 'name']
function getData(){
$("#output").html("<b>hi there</b>");
$.getJSON('https://ws.audioscrobbler.com/2.0/?method=artist.gettopalbums&artist=drake&api_key=22102f7d3a814de0736edf670bd2c771&format=json',function(result){
console.log(result);
let testarray = result[0]['album'];
let newdata = [];
for (let i = 0; i < result.length; i++) {
testarray= result[i]['album']
console.log(testarray)
let item = []
item[0] = testarray[i]['playcount']
item[1] = testarray[i]['name']
newdata[j] = item
console.log(newdata);
}
console.log(newdata)
})
}
Let's first take a look at the data you are working with:
result = {
"topalbums":
{
"album":
[
{
"name": "So Far Gone",
"playcount": 12543719,
"mbid": "f05567cc-6ed3-40e0-bad1-7812478eecbe",
"url": "https://www.last.fm/music/Drake/So+Far+Gone",
"artist": { ... }
"image": [ ... ]
},
...
],
"#attr": { ... }
}
}
You are gettin an object that has a property with a key called topalbums. Top albums has two properties; an array called album and an object called #attr.
From the looks of it, you want to access the objects inside of the album array, and more specifically name and playcount.
Given the data you are working with I assume this is what you would be looking for:
let newdata =
[
{
"playcount": 123123
"name": "album name1"
},
{
"playcount": 12456543
"name": "album name2"
},
...
]
To achieve this you can alter your code in the following fashion:
function getData(){
$("#output").html("<b>hi there</b>");
$.getJSON('https://ws.audioscrobbler.com/2.0/?method=artist.gettopalbums&artist=drake&api_key=22102f7d3a814de0736edf670bd2c771&format=json',function(result){
console.log(result);
let albumArray = result["topalbums"]["album"]; // This gets you the album array
let newdata = [];
for (let i = 0; i < albumArray.length; i++) {
const albumSummary = {} // Create a new object
albumSummary["name"] = albumArray.name // Add name to the object
albumSummary["playcount"] = albumArray.playcount // Add playcount to the object
newdata.push(albumSummary) // Add the object to the array
}
console.log(newdata)
})
}
Alternatively, if you don't want an array of objects but an array of arrays like this [['playcount', 'name']...], you can alter the code above like this:
function getData(){
$("#output").html("<b>hi there</b>");
$.getJSON('https://ws.audioscrobbler.com/2.0/?method=artist.gettopalbums&artist=drake&api_key=22102f7d3a814de0736edf670bd2c771&format=json',function(result){
console.log(result);
let albumArray = result["topalbums"]["album"]; // This gets you the album array
let newdata = [];
for (let i = 0; i < albumArray.length; i++) {
const albumSummary = [] // Create a new array
albumSummary.push(albumArray.name) // Add name to the array
albumSummary.push(albumArray.playcount) // Add playcount to the array
newdata.push(albumSummary) // Add the array to the array
}
console.log(newdata)
})
}
Hope this helps!
Related
I'm asking your help for the following code:
function vimeoImport() {
let videosToBeImported = [{
uri: "/videos/442638455",
name: "FOMME_1387_VD1",
modifed_time: "2020-07-29T09:24:48+00:00"
},{
uri: "/videos/442056086",
name: "FOMME_1387_VD2",
modifed_time: "2020-07-29T09:25:27+00:00"
},{
uri: "/videos/442638455",
name: "FOMME_2387_VD1",
modifed_time: "2020-07-29T09:24:48+00:00"
}];
let frtVideoUrlValues = {};
for (var index in videosToBeImported) {
var videos = videosToBeImported[index];
let videoName = videos.name;
let splitName = videoName.split('_');
let targetedVariationGroup = splitName[0].concat('_', splitName[1]);
let positionvideo = splitName[2];
let variationGroupParams = {};
variationGroupParams[positionvideo] = videos.uri;
if (targetedVariationGroup in frtVideoUrlValues) {
frtVideoUrlValues[targetedVariationGroup] += variationGroupParams;
} else {
frtVideoUrlValues[targetedVariationGroup] = variationGroupParams;
}
}
}
I tried to add a key/value pair (the key is a variable) in the targetedVariationGroup object which is in the frtVideoUrlValues object. When I try, I see the new key/value pair in the targetedVariationGroup but the merge is not functional and the 2 objects are not accessible:
And I try to obtain an object like this:
As, you didn't provide any output format, I am guessing the output should look like as follows(If this is not what you've wanted, pls provide proper output format):
{
FOMME_1387: [
{ VD1: '/videos/442638455' },
{ VD2: '/videos/442056086' }
],
FOMME_2387: [
{ VD1: '/videos/442638455' }
]
}
Now, to achieve this you should write code as follow:
function vimeoImport() {
let videosToBeImported = [
{
uri: "/videos/442638455",
name: "FOMME_1387_VD1",
modifed_time: "2020-07-29T09:24:48+00:00"
},
{
uri: "/videos/442056086",
name: "FOMME_1387_VD2",
modifed_time: "2020-07-29T09:25:27+00:00"
},
{
uri: "/videos/442638455",
name: "FOMME_2387_VD1",
modifed_time: "2020-07-29T09:24:48+00:00"
}
];
let frtVideoUrlValues = {};
for (var index in videosToBeImported) {
var videos = videosToBeImported[index];
let videoName = videos.name;
let splitName = videoName.split('_');
let targetedVariationGroup = splitName[0].concat('_', splitName[1]);
let positionvideo = splitName[2];
let variationGroupParams = {};
variationGroupParams[positionvideo] = videos.uri;
// here are the changes I've made
if(frtVideoUrlValues[targetedVariationGroup] === undefined) {
frtVideoUrlValues[targetedVariationGroup] = [];
}
frtVideoUrlValues[targetedVariationGroup].push(variationGroupParams);
}
console.log(frtVideoUrlValues);
}
vimeoImport();
The problem with your code is, you're using + to add object with another object, but + is only used to concat string in javascript. Instead of what you're doing, you should push objects into array. To add new elements in an array, you've to use push() method.
Also, notice, if key targetedVariationGroup in frtVideoUrlValues is undefined, I've assigned an empty array to targetedVariationGroup as follows:
frtVideoUrlValues[targetedVariationGroup] = [];
and then, pushed variationGroupParams object in the array as follows:
frtVideoUrlValues[targetedVariationGroup].push(variationGroupParams);
I was wondering how i could merge these two objects retrieve the tag values and store them in an array. This data is also coming from a json response so incoming data should be pushed onto the end of the new array.
so it would look something like this
["2011 LDI", "2012 LDI"]
array with incoming data:
["2011 LDI", "2012 LDI","2013 LDI"]
Here is what I am getting back in my console.log:
[19-08-25 21:58:32:055 PDT] []
[19-08-25 21:58:32:056 PDT] []
Here are the two objects of arrays i am trying to merge:
{date_added=2019-08-26 04:19:00.112083, tag=LDI 2011}
{date_added=2019-08-26 04:19:00.112089, tag=LDI 2012}
and I want it to look like this
[LDI 2011, LDI 2012]
and how I am trying to do it.
var tagtest = [];
var tags = message.student_detail.student_tags,
i = 0,
len = tags.length;
for (i; i < len; i++) {
var obj = tags[i];
for (a in obj) {
}
Array.prototype.push(tags, tagtest);
Logger.log(tagtest)
}
Based on your desired output ([LDI 2011, LDI 2012]), You may want the only tag values from the array, If this is what you are looking for then .map() will help you
const array = [
{
date_added: '2019-08-26',
tag: 'LDI 2011'
},
{
date_added: '2019-08-26',
tag: 'LDI 2012'
}];
const tags = array.map((r) => {
const chunk = r.tag.split(' ');
return `${chunk[1]} ${chunk[0]}`;
} );
console.log(tags);
A for in loop is a great way to work with objects. I updated the code above so that it was actually an array of objects, not an error. See below :)
var data = [{date_added: "2019-08-26 04:19:00.112083", tag: "LDI 2011"},
{date_added: "2019-08-26 04:19:00.112089", tag: "LDI 2012"}];
var newArr = [];
for(var item in data) {
newArr.push(data[item].tag);
}
console.log(newArr);
Given the following array in vue.js:
packageMaps: Object
packageMap_0: Object
Id: 16
PackageType: "flag_list"
ProductCode: "F-BannerBase"
packageMap_1: Object
Id: 82
PackageType: "flag_list"
ProductCode: "F-TeardropBanner"
....
....
...and given the value F-TeardropBanner, how can I access the given array and return the relevant PackageType?
populatePackageList(productCode) {
let packageList = [];
let packageType = '';
for(let key in this.packageMaps.ProductCode) {
if(productCode === this.packageMaps[key];
// not sure what to do here or if I am on the right track
}
this.formData.packageList = Object.assign({}, this.formData.packageList, packageList);
},
If your response data is BIG in size, convert that response data to another object with (key,value) as {product Id : packageMap_x_object}, like below, thus retrieval will be fast
let newPackageMaps = {
"F-BannerBase": packageMap_0_Object
"F-TeardropBanner":packageMap_1_Object
..........
..........
}
populatePackageList(productCode) {
//---------- more code----------------
let packageMapItem = newPackageMaps[productCode]?
newPackageMaps[productCode]:null;
//---------- more code ----------
}
OR in simple you can use a for..in loop,
for (let packageMap in this.packageMaps) {
if(packageMap.ProductCode == input_ProductCode ){
// more code
break;
}
}
I want to find strings that has data from the strings from the array 2 in the array1 and save result as separate uniq array.
As can you see I search for not exact values. From the array1 values I know only part of the information, and I want to find the complete strings, with that information, in array1. And at the end I want to save what I found. So, I don't have a problem with finding here, but a problem with saving in the valid single JSON.
Array examples:
Array #1:
{
"overflow": [
"id:address:name:location:email",
...
"id2:address2:name2:location2:email2"
]
}
Array #2:
[
"location:email",
...
"location2:email2"
]
Code:
resultArr: function() {
var arr1 = '/var/log/1.json';
var arr2 = '/var/log/2.json';
var arrResult = '/var/log/result.json';
var arr2Obj = JSON.parse(fs.readFileSync(arr2, 'utf-8'));
for (var i = 0; i < arr2Obj.length; i++) {
var arr1Obj = JSON.parse(fs.readFileSync(arr1, 'utf-8'));
arr1Obj.overflow = arr1Obj.overflow.filter(function(e) {
return e.includes(arr2Obj[i])
});
fs.appendFile(arrResult, JSON.stringify(arr1Obj, null, 2), 'utf-8');
}
}
My result:
[{
"overflow": [
"id:address:name:location:email"
]
}{
"overflow": [
"id54:address54:name54:location54:email56"
]
}{
"overflow": [
"id2:address2:name2:location2:email2",
"id6:address6:name6:location2:email2"
]
}
What I really want:
{
"overflow": [
"id:address:name:location:email",
"id54:address54:name54:location54:email56",
"id6:address6:name6:location2:email2",
"id2:address2:name2:location2:email2"
]
}
Instead of reading the file again and again, and appending to the result repeatedly, just do both actions only once. All the rest should happen in memory.
You will also get better results (no risk for duplicates in result) when you swap the loops: put the filter action as the outer loop. For the inner loop you can use some, since one match is enough for the entry to be included:
resultArr: function() {
var arr1 = '/var/log/1.json',
arr2 = '/var/log/2.json',
arrResult = '/var/log/result.json',
arr2Obj = JSON.parse(fs.readFileSync(arr2, 'utf-8')),
arr1Obj = JSON.parse(fs.readFileSync(arr1, 'utf-8'));
arr1Obj.overflow = arr1Obj.overflow.filter(function(e) {
return arr2Obj.some(function (f) {
return e.includes(f)
});
});
fs.writeFileSync(arrResult, JSON.stringify(arr1Obj, null, 2), 'utf-8');
}
At each iteration, you're creating a new object and appening it to a file.
JSON is not a good format to append to.
You're replacing the array instead of adding fields to it.
You can do it that way, it should work :
resultArr: () => {
let arr1 = '/var/log/1.json';
let arr2 = '/var/log/2.json';
let arrResult = '/var/log/result.json';
let arr2Obj = JSON.parse(fs.readFileSync(arr2, 'utf-8'));
let arr1Obj = JSON.parse(fs.readFileSync(arr1, 'utf-8')); // reading only one time
arr1Obj.overflow = arr2Obj.map(value => {
return arr1Obj.overflow.filter(e => return e.includes(value))
});
fs.writeFileSync(arrResult, JSON.stringify(arr1Obj, null, 2), 'utf-8'); //Writing only one time
}
Array.map() executes the closure for each field in your array and group all the values returned by the closure in another array.
I also replaced some keywords to make your code more ES6 compliant. I you really want to append, you should use CSV and not JSON.
I am new to Javascript (familiar with C/C++) and I am trying to parse out an XML file and store it in an Array of Objects. The structure is similar to a bullet list where there is one main List item and possibly multiple List subitems:
var MenuLine =
[{
label : "null",
icon : "null",
Subitem:
[{
label : "null",
icon : "null"
}]
}];
Which allows me to use the following syntax:
var someRandomSubitemText = MenuLine[2].Subitem[4].label;
I tried populating this array using the .push method:
var tempMenuLine = [];
var tempSubitem = [];
$(xml).find("item").each(function()
{
tempMenuLine.label = $(xml).children("label").text();
tempMenuLine.icon = $(xml).children("icon").text();
$(this).children("subitem").each(function()
{
tempSubitem.label = $(this).children("label").text();
tempSubitem.icon = $(this).children("icon").text();
tempMenuLine.Subitem.push(tempSubitem);
});
MenuLine.push(tempMenuLine);
});
However this does not work since the .push method passes a reference to tempMenuLine and I am overwriting tempMenuLine with each iteration. Is there a way that I could write directly to the MenuLine array using something similar to the following syntax?
$(xml).find("item").each(function(index1)
{
MenuLine[index1].label = $(xml).children("label").text();
MenuLine[index1].icon = $(xml).children("icon").text();
$(this).children("subitem").each(function(index2)
{
MenuLine[index1].Subitem[index2].label = $(this).children("label").text();
MenuLine[index1].Subitem[index2].icon = $(this).children("icon").text();
});
});
Move your temp var declarations inside of your loops:
$(xml).find("item").each(function() {
var tempMenuLine = [];
tempMenuLine[0].label = $(xml).children("label").text();
tempMenuLine[0].icon = $(xml).children("icon").text();
tempMenuLine[0].Subitem = []
$(this).children("subitem").each(function(){
var tempSubitem = [];
tempSubitem[0].label = $(this).children("label").text();
tempSubitem[0].icon = $(this).children("icon").text();
tempMenuLine[0].Subitem.push(tempSubitem);
});
MenuLine.push(tempMenuLine);
});
This way, you're initializing a new item for each iteration of the loops, removing the "link" it had to the previous item.
A recursive solution just for fun.
var MenuLine = Xml2Array(xmlText, 'item');
function Xml2Array(xmlDocument, itemName) {
if (!$(itemName, xmlDocument).length) {
return;
}
var tmpArray = [];
$(itemName, xmlDocument).each(function() {
tmpArray.push({
label: $('label', this).first().text(),
icon: $('icon', this).first().text(),
Subitem: Xml2Array(this, 'subitem')
});
});
return tmpArray;
}