I'm grabbing a list of elements ids thusly.
var menus = $(".menu").map(function(){
return this.id;
});
Which returns something like:
["lunch", "appetizers", "soup", "salads", "seafood", "noodles", "stir_fry", "curry", "kids", "steak", "dessert", "sides"]
For each item in the array I want to grab some JSON data.
$.each(menus,function(i) {
var list = menus[i],
meal = data.menu.list,
items = '<li><h3>' + meal.name + '</h3><p>' + meal.desc + '</p></li>';
$('#'+list+".menu").append(items);
});
Such that data.menu.list would be data.menu.lunch, data.menu.appetizers, etc.
The JSON is structured like so:
{
"menu": {
"lunch": [{
"name": "Kao PAdd",
"desc": "Fried rice with onions, green onions, snow peas, and egg / Chicken, vegetarian / Shrimp or tofu (Add $1)"
}
Any thoughts that don't involve eval()?
EDIT:
I when I do this:
$.each(data.menu,function(i) {
console.log(data.menu[i].key);
});
the console gives me:
Object {lunch: Array(14), appetizer: Array(11)}
All I really want is to access those arrays.
console.log(data.menu[i].name)
gives me a pair of undefineds.
That’s a brilliant question, Sir!
No matter how you retrieve your menus, strToVar() will do the task.
This code converts strings from array to variable names:
Solution:
var strToVar = (str,val) => this[str] = val;
Example:
var menus = ["lunch", "appetizers", "soup", "salads", "seafood", "noodles",
"stir_fry", "curry", "kids", "steak", "dessert", "sides"];
menus.forEach(strToVar);
prompt("[lunch, appetizers, soup, salads, seafood, noodles, " +
"stir_fry, curry, kids, steak, dessert, sides]",
[lunch, appetizers, soup, salads, seafood, noodles,
stir_fry, curry, kids, steak, dessert, sides]);
Give me all your points.
If you're looking for parsing JSON string to object here you go:
var jsonString = '{"data":{"item":{"id":1,"value":"foo"}}}';
var jsonObj = JSON.parse(jsonString);
console.log(jsonObj.data.item.value);
The problem was, I didn't understand what I really wanted to do. I asked the wrong question (although it's an interesting one, so I'll leave it up).
I thought I needed to generate my variable list from the HTML ids, but that was a mistake. What I needed was simply another for loop (or jQuery each());
$.each(data.menu, function(i) {
var list = data.menu[i],
menus = [];
$.each(list, function(x) {
var items = '<li><h3>' + list[x].name + '</h3><p>' + list[x].desc + '</p></li>';
menus.push(items)
});
$('#' + i).append(menus);
});
Your $.each function should be:
$.each(menus, function(i, list) { // the second parameter is list so we don't need menus[i]
var meal = data.menu[list], // use of bracket notation
items = '<li><h3>' + meal.name + '</h3><p>' + meal.desc + '</p></li>';
$('#' + list).append(items);
// ^^^ no need for the ".menu" as IDs alone are sufficient (assuming you have unique IDs, otherwise you have a problem)
});
Docs on MDN for bracket notation.
As per my understanding you want to achieve something like this :
var menus = ["lunch", "appetizers", "soup", "salads"];
var menuList = [
{
"name":"lunch",
"description":"description1"
},
{
"name":"appetizers",
"description":"description2"
},
{
"name":"soup",
"description":"description3"
},
{
"name":"salads",
"description":"description4"
}
]
var menu = {};
for(var i in menus) {
menu[menus[i]] = [{
"name": menuList[i].name,
"desc": menuList[i].description
}];
}
console.log(menu);
Related
I came across an exercise in freeCodeCamp to convert json data to html. Here, I was asked to copy paste a jquery which I didn't understand.
json.forEach(function(val) {
var keys = Object.keys(val);
html += "<div class = 'cat'>";
keys.forEach(function(key) {
html += "<strong>" + key + "</strong>: " + val[key] + "<br>";
});
html += "</div><br>";
});
This is my json
[
{
"id":0,
"imageLink":"https://s3.amazonaws.com/freecodecamp/funny-cat.jpg",
"altText":"A white cat wearing a green helmet shaped melon on it's head. ",
"codeNames":[
"Juggernaut",
"Mrs. Wallace",
"Buttercup"
]
},
{
"id":1,
"imageLink":"https://s3.amazonaws.com/freecodecamp/grumpy-cat.jpg",
"altText":"A white cat with blue eys, looking very grumpy. ",
"codeNames":[
"Oscar",
"Scrooge",
"Tyrion"
]
},
{
"id":2,
"imageLink":"https://s3.amazonaws.com/freecodecamp/mischievous-cat.jpg",
"altText":"A ginger cat with one eye closed and mouth in a grin-like expression. Looking very mischievous. ",
"codeNames":[
"The Doctor",
"Loki",
"Joker"
]
}
]
Can anyone help me to break down this code and tell what each line in the code does? For example I don't know what Object.keys does. Is Object an inbuilt instance?
The Object.keys() method returns an array of a given object's own enumerable properties.
var keys = Object.keys(val);
Here 'keys' is the array form of your json.
According to the JSON you provided the array has 3 objects.
You can also write
Object.keys(val).forEach(function(key){
//something
});
instead of
var keys = Object.keys(val);
keys.forEach(function(key) {
//something
});
Inside the loop the key returns the the key of your object i.e.
id, imageLink etc
and
val[key] return corresponding values e.g.
0, "https://s3.amazonaws.com/freecodecamp/funny-cat.jpg" to be more specific.
From MDN
Object.keys() returns an array whose elements are strings corresponding to the enumerable properties found directly upon object. The ordering of the properties is the same as that given by looping over the properties of the object manually.
The purpose of the code is to generate html by using key and corresponding value.
var json = [
{
"id":0,
"imageLink":"https://s3.amazonaws.com/freecodecamp/funny-cat.jpg",
"altText":"A white cat wearing a green helmet shaped melon on it's head. ",
"codeNames":[
"Juggernaut",
"Mrs. Wallace",
"Buttercup"
]
},
{
"id":1,
"imageLink":"https://s3.amazonaws.com/freecodecamp/grumpy-cat.jpg",
"altText":"A white cat with blue eys, looking very grumpy. ",
"codeNames":[
"Oscar",
"Scrooge",
"Tyrion"
]
},
{
"id":2,
"imageLink":"https://s3.amazonaws.com/freecodecamp/mischievous-cat.jpg",
"altText":"A ginger cat with one eye closed and mouth in a grin-like expression. Looking very mischievous. ",
"codeNames":[
"The Doctor",
"Loki",
"Joker"
]
}
]
var html = "";
//iterating through all the item one by one.
json.forEach(function(val) {
//getting all the keys in val (current array item)
var keys = Object.keys(val);
//assigning HTML string to the variable html
html += "<div class = 'cat'>";
//iterating through all the keys presented in val (current array item)
keys.forEach(function(key) {
//appending more HTML string with key and value aginst that key;
html += "<strong>" + key + "</strong>: " + val[key] + "<br>";
});
//final HTML sting is appending to close the DIV element.
html += "</div><br>";
});
document.body.innerHTML = html;
I'm making a outfit randomizer. But I would like to add some rules to it to prevent weird outfits like a white tie on a white shirt. Or any tie on a graphic tee. Or wearing a turtleneck over a shirt.
This is the code, so far:
var shirts = ["White", "navy", "light blue", "gray"];
var pants = ["black", "navy", "gray"];
var ties = ["red and blue squares", "purple", "white", "red"];
var random_shirt = shirts[Math.floor(Math.random()*shirts.length)];
var random_pants = pants[Math.floor(Math.random()*pants.length)];
var random_tie = ties[Math.floor(Math.random()*ties.length)];
document.write( " shirt: " + random_shirt + " pants: " + random_pants + " tie: " + random_tie);
I know it's done with if's and else's, but I don't know how.
Please forgive my JS illiteracy. I learned it but never actually used it. Until now.
Thanks
There are severals ways of doing this, this is my suggestion:
You can filter the pants array based on the result of random shirt
var random_shirt = [random logic];
/*
This will iterate over your pants array, returning a filtered array
with containing the items that returned true
item: the actual item
index: index of the actual item
array: original array
*/
filtered_pants = pants.filter(function(item, index, array) {
if (item == random_shirt) {
// This item won't be in the filtered array
return false;
}
if ([another custom rule]) {
return false;
}
/*
After passing all the rules return true to include this item in
the filtered array
*/
return true;
});
// Now shuffle over the filtered array
var random_pants = filtered_pants[Math.floor(Math.random()*pants.length)];
Then just repeat it with the tie
Make sure to learn the documentation for the filter method ->
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Alternatively you can use the reduce method which is similar -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
If you don't quite understand these methods, watch this playlist, it'll help a lot -> https://www.youtube.com/watch?v=BMUiFMZr7vk&list=PL0zVEGEvSaeEd9hlmCXrk5yUyqUag-n84
I am currently creating a tool that allows users to put in their state and category to see what the 3 price plans are. These 2 selections (state/category) will be picked via select field, and the data containing these numbers is in a JSON file:
[{
"Alabama/Category1/Price1":"$123,123 ",
"Alabama/Category1/Price2":"$123,123 ",
"Alabama/Category1/Price3":"$123,123 ",
"Alabama/Category2/Price1":"$345,345 ",
"Alabama/Category2/Price2":"$345,345 ",
"Alabama/Category2/Price3":"$345,345 ",
"Alabama/Category3/Price1":"$456,789 ",
"Alabama/Category3/Price2":"$456,789 ",
"Alabama/Category3/Price3":"$456,789 ",
"Alabama/Category4/Price1":"$321,321 ",
"Alabama/Category4/Price2":"$321,321 ",
"Alabama/Category4/Price3":"$321,321 ",
"Alaska/Category1/Price1":"$123,123 ",
"Alaska/Category1/Price2":"$123,123 ",
"Alaska/Category1/Price3":"$123,123 ",
"Alaska/Category2/Price1":"$345,345 ",
"Alaska/Category2/Price2":"$345,345 ",
"Alaska/Category2/Price3":"$345,345 ",
"Alaska/Category3/Price1":"$456,789 ",
"Alaska/Category3/Price2":"$456,789 ",
"Alaska/Category3/Price3":"$456,789 ",
"Alaska/Category4/Price1":"$321,321 ",
"Alaska/Category4/Price2":"$321,321 ",
"Alaska/Category4/Price3":"$321,321 ",
}]
Basically on button click, I would like to loop through the JSON file and get the State/Category based off the users selections. Being that there are some "/"'s in that key path, I tried stashing the users selection in a variable, so that I could target each price point and display them on the page. My way of trying that was stashing it in a variable like so:
var test = stateSelected + '/' + categorySelected + '/Price1';
This, however does not work, and was wondering if there was any additional insight as to how to achieve this? Reading some other material, it seems some are recommending to use $.parseJSON, but that was not working either. For that I used:
$.getJSON("json_data.json", function(obj) {
$.each($.parseJSON(data), function(key, value) {
//code here
});
});
Sorry for the longevity on this, but too many times on this site I have seen people not give enough information for people to be able to understand the real issue, and I hope I have outlined mine correctly. Any help on this would be appreciated. Thanks!
EDIT: Also, if you think there is a different way to present the JSON data other than the way I have it here, let me know. The data will be updated via spreadsheet and I used an Excel -> JSON translator tool and this was the way it spit back out the data.
I'd format the JSON in the following way:
var options = {
Alabama: {
Category1: {
Price1: "$123, 123",
Price2: "$123, 123",
}
}
}
and then:
var priceOptions = options[stateSelected][categorySelected];
If you cannot alter the JSON then you'll have to iterate through each key in the object:
function getPricePoints(state, category, onComplete)
{
$.getJSON("json_data.json", function(obj)
{
var result = {};
for(key in obj)
{
if(obj.hasOwnProperty(key) && key.indexOf(state + "/" + category + "/") == 0)
{
result[key] = obj[key];
}
}
onComplete(result);
});
}
If you can alter the way the JSON is represented then why not store the data like so:
var options = {
"Alabama/Category1" : {
"Price1":"$123,123 ",
"Price2":"$123,123 ",
"Price3":"$123,123 "
},
"Alabama/Category2" : {
"/Price1":"$345,345 ",
"Price2":"$345,345 ",
"Price3":"$345,345 "
}
...
}
Then you get slash the user's inputs and get all the prices options for that combination of state and category?
test = stateSelected + '/' + categorySelected;
var priceOptions = options[test];
I have an array (json) of products (around 5000) where each product is represented in two arrays as shown below;
["PC01","Product 1","11"],
["PC01","Product 1","17"]
The only difference is, the 11 and 17 strings both representing the first and second price of the product.
I am trying to find a way to merge this array into a single one so that each product is represented as one such as:
["PC01", "Product 1", "11", "17"]
I have tried looping and forming an object of products which I found not quite safe due to various reasons and one of them being the order of the prices are unknown. So at first I might get the highest price first and lowest price second while on the other hand, another array would have the lowest one first and highest the second.. This is my current code;
var products = [];
$.getJSON('data.json', function (data) {
$.each(data, function (key, val) {
if (!key == 0) {
// because I use the previous arrays info,
// only start if we HAVE a previous array hence;
if (data[key][0] != data[key - 1][0]) {
var o = {}
o.ProductCode = val[0];
o.ProductName = val[1];
o.Price1 = val[3];
o.Price2 = data[key - 1][3];
products.push(o);
}
}
});
});
As I said, this relies on the fact that each product exists as two arrays and assumes the second price is the highest.
So, I am basically trying to find the most optimal way to parse the json to merge all double arrays and would be grateful if you could give me some ideas..
EDIT:
Sample Data:
Note: Sample data have more information than I initially wrote in my question such as stock quantity, VAT rate etc. but omitted by me to prevent any confusions.
[
[
"AD.0001 ",
"AD ALOE VERA MOUTHWASH w�th FLUORIDE 250ML ",
" 691",
" 11.51",
" 16",
" 96"
],
[
"AD.0001 ",
"AD ALOE VERA MOUTHWASH w�th FLUORIDE 250ML ",
" 691",
" 17",
" 16",
" 96"
],
[
"AD.0002 ",
"AD ALOE VERA MOUTHWASH 250ML ",
" 692",
" 11.51",
" 16",
" 75"
],
[
"AD.0002 ",
"AD ALOE VERA MOUTHWASH 250ML ",
" 692",
" 17",
" 16",
" 75"
]
]
Try something like this:
var productsbycode = {};
var products = [];
$.getJSON('data.json', function (data) {
$.each(data, function (key, val) {
if(typeof productsbycode[val[0]] !== "object"){
productsbycode[val[0]] = {name: val[1], prices: [val[2]]};
} else{
productsbycode[val[0]].prices.push(val[2]);
}
});
$.each(productsbycode, function(key, val){
var price1 = val['prices'][0];
var price2 = val['prices'][1];
if(price1 < price2){
products.push([key, val['name'], price1, price2]);
} else{
products.push([key, val['name'], price2, price1]);
}
});
});
JSFiddle.
It works in any order and it does what you asked.
Update: The prices will now show the lowest first and then the highest.
If the 1 and 2 always follow each other just do this:
var products = [
["A", 1], ["A", 2],
["B", 5], ["B", 2],
["C", 1], ["C", 2]
];
document.getElementById('input').innerHTML = JSON.stringify(products);
var i = 0;
while(i < products.length) {
var first = i,
second = i + 1;
if ( products[first][1] > products[second][1] ) {
first = i + 1; second = i; // just switch the index..
}
products[first].push(products[second][1]);
products.splice(second, 1);
i++;
}
document.getElementById('result').innerHTML = JSON.stringify(products);
input
<pre id="input"></pre>
<br>
result
<pre id="result"></pre>
More broadly, there's a cool library called Immutable.js which lets you manipulate complex JSON objects in a very clean way.
It provides methods to merge arrays and other arbitrary JSON objects and define your conflict resolution strategy.
There is Linq for JavaScript (linq.js), a free JavaScript library available at CodePlex:
https://linqjs.codeplex.com/
Like C# LINQ it has a .distinct method which can help you to remove duplicates, amongst most LINQ query methods you know from C# made available in JavaScript.
Example:
var list = [
{ one: 2, two: 4, three: 1 },
{ one: 4, two: 7, three: 5 },
{ one: 2, two: 4, three: 1 },
{ one: 7, two: 3, three: 2 },
];
Enumerable.From(list).Distinct("$.one")
.OrderBy("$.a").ThenBy("$.two").ThenBy("$.three")
.Select("$.one + ':' + $.two + ':' + $.three")
Gives you the result:
2:4:1
4:7:5
7:3:2
More about LINQ.js: see this answer at SO
I have the following javascript array:
[{
"id": "115",
"poster": "809",
"post": "alfa"
}, {
"id": "127",
"poster": "808",
"post": "beta"
}]
What do I need to do in order to extract the values into usable variables?
Try this,
var arr = [{"id":"115","poster":"809","post":"alfa"},{"id":"127","poster":"808","post":"beta"}];
for (i = 0; i < arr.length; i++)<br/>
document.write("id: " + arr[i].id + " poster: " + arr[i].poster + " post: " + arr[i].post + "<br/>");
What you have is an array with two elements
data = [a,b]
where both elements a and b are objects each having three fields (id,poster,post).
Recall that to access an element in the array at position i you simply write data[i] (this will access the ith element in your array i.e. one of the objects).
In order to access a field of the object a you simply use a.fieldName. For example a.id will access id field of object a. If you combine them both you can get data[i].fieldName to access field of specific object (for example data[0].id will return "115").
As a side note, array structures are iterable:
for(var i = 0;i<data.length;i++){
id = data[i].id;
post = data[i].post;
poster = data[i].poster;
document.write(id+" "+post+" "+poster+"<br/>");
}
UPDATE: Example on jsFiddle