Problem with a JSON Object ( deep search ) - javascript

Hi Guys i have a big Problem, i've been trying to solve it for days.I have an entangled JSON Object ( http://ddragon.leagueoflegends.com/cdn/9.1.1/data/de_DE/runesReforged.json ) and for example this Array with my ID's in it.
0: 8214 1: 8112 2: 8005 3: 8010 4: 8112 5: 8359 6: 8437 7: 9923 8: 8112 9: 8021
And I want the id to be searched for with the help of this array in the json Object. And after a match, the content of "icon" should be returned,
but i dont know how :(
I tried it on so many ways, but i dont have the result that i want. The ID's are among others under the_json_object[0].slots[0].runes[0].id
I read that you could solve it with recursive functions but I tried and did not get the desired result.
Maybe you guys can help me :) i would be very thankful

If I've understood you correctly you could do something roughly as follows:
var ids = [8214,8112,8005,8010,8112,8359,8437,9923,8112,8021];
var results = [];
ids.map(function(id) {
results.push({key: id, icon: ''});
});
Then given your object you could map through it's children as folllows:
the_json_object.map(function(item){
item.slots.map(function(slot){
slot.runes.map(function(rune){
if(ids.indexOf(rune.id) != -1) {
results.map(function(result){
if(result.key == rune.id) result.icon = rune.icon;
});
}
});
});
});
var icons = [];
results.map(function(result){
icons.push(result.icon);
});
logging the icons object would then provide you a string array of icons as follows:
["perk-images/Styles/Domination/Electrocute/Electrocute.png", "perk-images/Styles/Domination/HailOfBlades/HailOfBlades.png", "perk-images/Styles/Inspiration/Kleptomancy/Kleptomancy.png", "perk-images/Styles/Precision/PressTheAttack/PressTheAttack.png", "perk-images/Styles/Precision/FleetFootwork/FleetFootwork.png", "perk-images/Styles/Precision/Conqueror/Conqueror.png", "perk-images/Styles/Resolve/GraspOfTheUndying/GraspOfTheUndying.png", "perk-images/Styles/Sorcery/SummonAery/SummonAery.png"]
Hope this helps.
Matt

I think the suitable way would be to sort data. You can do this by splitting the string.
If you split the string on the basis of White spaces you can get key value pairs.
For example from string *
0:8214 1:8112 2:8005 3:8010 4:8112 5:8359 6:8437 7:9923 8:8112 9:8021
var res = str.split(" ");
if you split with white space it will provide you with key value pairs from which you can form a list of objects and it will be easy for you search from it.

If you want an flat array with the all the needed icons, you could use something like this:
let the_runes = [ 8214, 8112, 8005 /* ... */ ];
let the_icons = [];
for (let first_level_obj of the_json_object) {
for (let slot_obj of first_level_obj.slots) {
for (let rune_obj of slot_obj.runes) {
if (the_runes.includes(rune_obj.id)) {
the_icons.push({
id: rune_obj.id,
icon: rune_obj.icon
});
}
}
}
}
The the_icons-array will hold objects with id and its corresponding icon as its properties.

Related

Function returning object instead of Array, unable to .Map

I'm parsing an order feed to identify duplicate items bought and group them with a quantity for upload. However, when I try to map the resulting array, it's showing [object Object], which makes me think something's converting the return into an object rather than an array.
The function is as follows:
function compressedOrder (original) {
var compressed = [];
// make a copy of the input array
// first loop goes over every element
for (var i = 0; i < original.length; i++) {
var myCount = 1;
var a = new Object();
// loop over every element in the copy and see if it's the same
for (var w = i+1; w < original.length; w++) {
if (original[w] && original[i]) {
if (original[i].sku == original[w].sku) {
// increase amount of times duplicate is found
myCount++;
delete original[w];
}
}
}
if (original[i]) {
a.sku = original[i].sku;
a.price = original[i].price;
a.qtty = myCount;
compressed.push(a);
}
}
return compressed;
}
And the JS code calling that function is:
contents: compressedOrder(item.lineItems).map(indiv => ({
"id": indiv.sku,
"price": indiv.price,
"quantity": indiv.qtty
}))
The result is:
contents: [ [Object], [Object], [Object], [Object] ]
When I JSON.stringify() the output, I can see that it's pulling the correct info from the function, but I can't figure out how to get the calling function to pull it as an array that can then be mapped rather than as an object.
The correct output, which sits within a much larger feed that gets uploaded, should look like this:
contents:
[{"id":"sku1","price":17.50,"quantity":2},{"id":"sku2","price":27.30,"quantity":3}]
{It's probably something dead simple and obvious, but I've been breaking my head over this (much larger) programme till 4am this morning, so my head's probably not in the right place}
Turns out the code was correct all along, but I was running into a limitation of the console itself. I was able to verify this by simply working with the hard-coded values, and then querying the nested array separately.
Thanks anyway for your help and input everyone.
contents: compressedOrder(item.lineItems).map(indiv => ({
"id": indiv.sku,
"price": indiv.price,
"quantity": indiv.qtty
}))
In the code above the compressedOrder fucntion returns an array of objects where each object has sku, price and qtty attribute.
Further you are using a map on this array and returning an object again which has attributes id, price and quantity.
What do you expect from this.
Not sure what exactly solution you need but I've read your question and the comments, It looks like you need array of arrays as response.
So If I've understood your requirement correctly and you could use lodash then following piece of code might help you:
const _ = require('lodash');
const resp = [{key1:"value1"}, {key2:"value2"}].map(t => _.pairs(t));
console.log(resp);
P.S. It is assumed that compressedOrder response looks like array of objects.

Javascript ForEach on Array of Arrays

I am looping through a collection of blog posts to firstly push the username and ID of the blog author to a new array of arrays, and then secondly, count the number of blogs from each author. The code below achieves this; however, in the new array, the username and author ID are no longer separate items in the array, but seem to be concatenated into a single string. I need to retain them as separate items as I need to use both separately; how can I amend the result to achieve this?
var countAuthors = [];
blogAuthors = await Blog.find().populate('authors');
blogAuthors.forEach(function(blogAuthor){
countAuthors.push([blogAuthor.author.username, blogAuthor.author.id]);
})
console.log(countAuthors);
// Outputs as separate array items, as expected:
// [ 'author1', 5d7eed028c298b424b3fb5f1 ],
// [ 'author2', 5dd8aa254d74b30017dbfdd3 ],
var result = {};
countAuthors.forEach(function(x) {
result[x] = (result[x] || 0) + 1;
});
console.log(result);
// Username and author ID become a single string and cannot be accessed as separate array items
// 'author1,5d7eed028c298b424b3fb5f1': 15,
// 'author2,5dd8aa254d74b30017dbfdd3': 2,
Update:
Maybe I can explain a bit further WHY on what to do this. What I am aiming for is a table which displays the blog author's name alongside the number of blogs they have written. However, I also want the author name to link to their profile page, which requires the blogAuthor.author.id to do so. Hence, I need to still be able to access the author username and ID separately after executing the count. Thanks
You could use String.split().
For example:
let result = 'author1,5d7eed028c298b424b3fb5f1'.split(',')
would set result to:
['author1' , '5d7eed028c298b424b3fb5f1']
You can then access them individually like:
result[1] //'5d7eed028c298b424b3fb5f1'
Your issue is that you weren't splitting the x up in the foreach callback, and so the whole array was being converted to a string and being used as the key when inserting into the results object.
You can use array destructuring to split the author name and blog id, and use them to optionally adding a new entry to the result object, and then update that result.
countAuthors = [
['author1', 'bookId1'],
['author2', 'bookId2'],
['author1', 'bookId3'],
['author1', 'bookId4'],
['author2', 'bookId5']
]
var result = {};
countAuthors.forEach(([author, id]) => {
if (result[author] === undefined) {
result[author] = {count: 0, blogIds: []};
}
result[author].count += 1;
result[author].blogIds.push(id);
});
console.log(result);

set array as value in json format in Javascript

I want to add array as json value.
Json format is as follows.
json_data = [
'name':'Testing'
'email':'TestEmail'
'links':[
'test#test.com',
'test#test1.com',
'test#test3.com']
]
How can I set value of 'links' in javascript like that?
I did as follows.
links_array = [];
links_array =['testing','test2'];
json_data.links = links_array;
I wanted to append these two string but couldn't.
Any help would be appreciate.
Assuming that the syntax of your example is correct, you can use the "push" method for arrays.
json_data = {
'name':'Testing',
'email':'TestEmail',
'links':[]
};
json_data.links.push("test1#test.com");
json_data.links.push("test2#test.com");
json_data.links.push("test3#test.com");
You have to make little changes to make it work.
First thing, You have to replace initial square brackets with curly one. By doing this your object will become JSON Literal - a key value pair.
Second thing, You have missed commas after 'name':'Testing' and 'email':'TestEmail'
Below will work perfectly:
var json_data = {
'name':'Testing',
'email':'TestEmail',
'links':[
'test#test.com',
'test#test1.com',
'test#test3.com']
}
In addition to push as mentioned by #giovannilobitos you can use concat and do it all in one go.
var json_data = {
'name':'Testing',
'email':'TestEmail',
'links':[
'test#test.com',
'test#test1.com',
'test#test3.com'
]
};
var links_array = ['testing','test2'];
json_data.links = json_data.links.concat(links_array);
console.log(json_data.links);
On MDN's array reference you can find a more complete list of how to modify arrays in JavaScript.

Traverse nested maps / objects from keys in an array

I think a code sample is going to work a lot better than my vocabulary:
var keys = ['folder','name'];
var data = { folder: { name: 'Special Folder' } };
Given the two vars above, I'm looking for a way to dynamically use the array as a way to look up the object keys (sort of like a "path"). So I need to programmatically produce the following:
data['folder']['name'] // that would give me 'Special Folder'
Hopefully this makes sense, I just can't quite put all the pieces together.
TIA
var keys = ['folder','name'];
var data = { folder: { name: 'Special Folder' } };
for(var i=0;i<keys.length;i++){
data = data[keys[i]];
}
alert(data)

Problem creating array in javascript

i have a javascript code below.
bgCustom = { 'items':[], 'items_num':3, 'element':'#bg_custom_thumbs', 'next': '#bg_custom_next_thumb', 'prev': '#bg_custom_prev_thumb', 'width':165 };
//populate array
bgCustom.items = [["images/backgrounds/bear-ears_thumb.jpg", "bear-ears.jpg", "Bear-Hair"], ["images/backgrounds/blue-swirls_thumb.jpg", "blue-swirls.jpg", "WaterSmoke"]];
ho do i create bgCustom.items array dynamic. means i want a array list
[['val1_1','val1_2','val1_3'],['val2_1','val2_2','val2_3']]
Can any body help me.
You can add arrays to the end of the array:
bgCustomer.items.push(['val1_1','val1_2','val1_3']);
bgCustomer.items.push(['val2_1','val2_2','val2_3']);
You can also assign arrays at specific indexes. The array will automatically expand if you use an index outside the current size:
bgCustomer.items[0] = ['val1_1','val1_2','val1_3'];
bgCustomer.items[1] = ['val2_1','val2_2','val2_3'];
bgCustom = { 'items':[], 'items_num':3, 'element':'#bg_custom_thumbs', 'next': '#bg_custom_next_thumb', 'prev': '#bg_custom_prev_thumb', 'width':165 };
function PushToItems(a,b,c) {
var ar = [a,b,c];
bgCustom.items.push(ar);
}
PushToItems("images/backgrounds/bear-ears_thumb.jpg", "bear-ears.jpg", "Bear-Hair");
That should work for making it a little more dynamic.

Categories

Resources