Using javascript, I want to create an array that has the structure so that it can have all states within the country array. Each state would be an array consisting all the regions within it. And each region would contain all the health clubs within it. Something like this:
[Australia]=>array([NSW]=>array([Sydney]=>array(element1, element2, ...)));
So far I have tried many things including the code below:
$('#search-widget-data li').each(function(){
var dataElement = $(this);
searchWidgetData.push(dataElement.text());
alldata.push([dataElement.prevAll(".state:first").text(),
dataElement.prevAll(".region:first").text());
});
You can use a form like this:
var countries = [
{
name: "Australia",
states: [
{
name: "state1",
regions: [
{
name: "region1",
healthclubs: [
"healthclub1", "healthclub2"
]
},
{
name: "region2",
healthclubs: [
"healthclub1", "healthclub2"
]
}
]
},
{
name: "state2",
regions: [
{
name: "region1",
healthclubs: [
"healthclub1", "healthclub2"
]
}
]
}
]
},
{
name: "USA"
}
];
You may want to store your data structure in the JSON format which will make it easy for storage and working with as a JavaScript object.
You may try this one out.
var regArr[n1][n2];
but you need to specify the length of each inner array.
Related
I'm studying about JSON and its use cases. Suppose I have a recipe book and I have the following JSON to store recipes (I apologize if anything is wrong before hand, I'm just starting with this)
var recipeBook =
{
recipes:
[
{
name: 'Spaghetti',
ingredients:
[
{
ingredientName: 'Pasta',
requiredAmount: 1,
},
{
ingredientName: 'Tomato Sauce',
requiredAmount: 1,
}
]
},
{
name: 'Cereal',
ingredients:
[
{
ingredientName = 'Cereal Box',
requiredAmount = 1
},
{
ingredientName = 'Milk',
requiredAmount = '1'
}
]
}
]
}
Say I wanted to add a third recipe, or add a new ingredient to a recipe...I'm wondering what is the best option (code-wise) to add new data into this JSON.
I think propably the function you are looking for is https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push, for example
recipeBook.recipes.push({
name: 'Soup',
ingredients:
[
{
ingredientNam: 'Water',
requiredAmount: 1
},
{
ingredientName: 'Potatoes',
requiredAmount: 4
}
]
})
And for new ingredients it would be
recipeBook.recipes[0].ingredients.push(
{
ingredientName: 'Salt',
requiredAmount: 1
}
)
I would recomend you to use the name of the recipe as the key in the recipes, I mean:
var recipeBook =
{
recipes:
{
Spaghetti:
{
ingredients:
[
{
ingredientName: 'Pasta',
requiredAmount: 1,
},
{
ingredientName: 'Tomato Sauce',
requiredAmount: 1,
}
]
},
Cereal:
{
ingredients:
[
{
ingredientName: 'Cereal Box',
requiredAmount: 1
},
{
ingredientName: 'Milk',
requiredAmount: 1
}
]
}
}
}
This helps to get the recipe as
var spaghettiRecipe = recipeBook.recipes.Spaghetti
First, JSON vs. JS Objects
JSON isn't to be confused with generic objects in JavaScript. JSON is a "lightweight data-interchange format" that does its best to be both easy for humans to read and edit, yet also easy for computers to parse and generate. One of the main differences is that JSON has stricter syntax requirements than generic JS objects do.
What you've written is simply an object declaration in Javascript, rather than standard JSON. A JSON equivalent to your example data would look like this:
{
"recipes": [
{
"name": "Spaghetti",
"ingredients": [
{
"ingredientName": "Pasta",
"requiredAmount": 1
},
{
"ingredientName": "Tomato Sauce",
"requiredAmount": 1
}
]
},
{
"name": "Cereal",
"ingredients": [
{
"ingredientName": "Cereal Box",
"requiredAmount": 1
},
{
"ingredientName": "Milk",
"requiredAmount": 1
}
]
}
]
}
The specific distinctions here:
All property names are enclosed in double quotes "
All strings are enclosed in double quotes " rather than single '
Trailing commas that aren't followed by another key/ value pair or data structure aren't allowed
You could choose to omit the recipes property and keep just the array without the enclosing object, this would still be valid.
Also worth noting that prop = value is not allowed in either syntax, JS object declaration nor JSON.
A description of the full JSON spec is here if you're interested.
Manipulating JS Data
You asked what the best option code-wise is to add data to this JSON. Since JSON is just a format, it's not actually super relevant here, since it's primarily used for data storage and transport, and not for manipulation.
To work with data stored as JSON in Javascript, you can parse it in with the JSON.parse(string) method, which will read a JSON string and return an equivalent Javascipt object. You can then use standard object/ array manipulation methods and techniques on that resulting object, in this case using push() to add a new recipe onto the array.
Here is some sample code to add data to the object
//add recipe
recipeBook.recipes.push(newRecipe);
//add ingredient to recipe by name
var recipe = recipeBook.recipes.find(r => r.name == recipeName);
if (recipe) recipe.ingredients.add(newIngredient);
Also your Cereal object is using ingredientName = 'Cereal Box', which is invalid javascript syntax. You need to use : as in your spaghetti object.
Instantiating an object involves creating an object programmatically. I'm simplifying the code to make it easy:
var book = {}
function Recipe(name, ingredients) {
this.name = name;
this.ingredients = ingredients;
}
// instantiate it
var chicken_teriyaki = new Recipe('Teriyaki', ['new one', 'two', 'three'])
var fried_chicken = new Recipe('Fried Chicken', ['chicken', 'potato starch', 'oil'])
// add to book
book.chicken_teriyaki = chicken_teriyaki;
book.fried_chicken = fried_chicken;
// update recipe
book.chicken_teriyaki.ingredients.push('another yummy')
// view result
console.log('the book', book);
I've seen similar questions to this one but in different languages and I am struggling to create a JavaScript equivalent.
I am receiving an object and through a function I want to change the location of one (or more) of the properties. For example,
With the original object of
{
individual: [
{
dob: '2017-01-01',
isAuthorized: true,
},
],
business: [
{
taxId: '123',
},
],
product: {
code: '123',
},
}
I would like to change the location of isAuthorized to be in the first object inside of the business array instead of individual.
Like so
{
individual: [
{
dob: '2017-01-01',
},
],
business: [
{
taxId: '123',
isAuthorized: true,
},
],
product: {
code: '123',
},
}
So far I was trying to create an object that would contain the key name and location to change it to, e.g.
{
isAuthorized: obj.business[0]
}
And then loop over the original object as well as the object with the location values and then set the location of that key value pair.
Basically, in this function I want to see that if the original object contains a certain value (in this case isAuthorized) that it will take that key value pair and move it to the desired location.
What you want can easily be achieved by using loadsh, here's a working snippet of how to restructure based on defined structure map. Extended this example to match what you want.
The example is doing a deep clone, if you are fine modifying the original object then skip that step to avoid the overhead.
// input data
const data = {
individual: [
{
dob: '2017-01-01',
isAuthorized: true,
},
],
business: [
{
taxId: '123',
},
],
product: {
code: '123',
},
};
// the structure change map
const keyMap = {
'individual[0].isAuthorized': 'business[0].isAuthorized'
};
function parseData(data,keyMap) {
const newData = _.cloneDeep(data);
for( let [source,dest] of Object.entries(keyMap) ) {
_.set(newData,dest,_.get(newData,source));
_.unset(newData,source);
}
return newData;
}
console.log(parseData(data, keyMap));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
Note: loadsh's set consider any numeric value as an array index so if you are using a numeric object key then use loadash.setWith. I recommend reading examples in doc for a better understanding.
https://lodash.com/docs/4.17.15#set
I've fetched some data from XML document and assigned them into three variables. Root element name, array which contains all the names of root's children and second array with length of those children sub-nodes. I want to convert those variables into the JSON object in this way:
{ "root_name": {
"childName[0]": "lengthSubNodes[0]",
"childName[1]": "lengthSubNodes[1]",
"childName[2]": "lengthSubNodes[2]",
}
with this function:
function XMLtoJSON(rootName,childNames,childNumbers){
var xmlObject = {}
xmlObject[rootName] = {};
for(var i = 0; i < childNames.length; i++ ){
xmlObject[rootName][childNames[i]] = childNumbers[i];
}
}
Everything works fine. However when it comes to XML document with many root's children with the same name and length they appear just once like this:
{ "catalog": {
"book": 6
}
and should look like this:
{ "catalog": {
"book":6,
"book":6,
"book":6
}
Do you know how to fix it?
You cannot have multiple keys of the same name under one parent. Also, nodes in xml have an order, which is lost under a js map. So if you want a xml to json utility, you need to create yourself a json schema. Here is a simplistic example:
{
name: "catalog",
value: null,
children: [
{
name: "book",
value: 6
},
{
name: "book",
value: 6
},
{
name: "book",
value: 6
},
]
}
I want to create a multi-level JSON string with JS.
Scenario
3 countries with 5 grandfathers with 3 kids which whom also have 3 kids that have 5 friends.
I get the data from a external JSON file that looks like this.
{"countries":[
{
"name":"USA",
"grandfathers":[
{
"gFName":"Steve",
"grandfathersKid":[
{
"gFKName": "Linda",
"kid": [{
"name": "Steve JR",
"friends": [{
"name": "Kriss|John|Martin|Steven"
}]
}
]
}
]
}
]
}
]}
And now I want to store some of the countries with people and their relatives and friends in a a new JSON list that looks exactly as the list made in the external json file. I aim to use this "homemade" list later on in the script.
My initial response for this was
var tree = new Array();
tree = {};
var countries = new Array();
countries[0] = "canada";
countries[1] = "USA";
countries[2] = "Mexico";
countries[0][0] = "Steve"; //Lives in Canada
countries[0][0][0] = "Linda"; //Daughter of Steve
countries[0][0][0][0] = "Steve JR"; // Kid of Linda
countries[0][0][0][0][0] = "Kriss"; //Steves Friend
...
$.each(countries...function(index, value){
tree[index].country = value;
$.each(grandfathers...function(key, value){
tree[index].country[key].grandfather = value;
}
And so on, but this is not giving me the result I want. What am I doing wrong? And a more effective way than to take each of everything?
Third edit...
Is this the sort of thing you're trying to do?
var countries = $.map(oldCountries || [], function(country) {
return {
name: country.name,
people: $.map(country.grandfathers || [], function(gpa) {
return {
name: gpa.gFName,
children: $.map(gpa.grandfathersKid || [], function(parent) {
return {
name: parent.gFKName,
children: $.map(parent.kid || [], function(kid) {
return {
name: kid.name,
friends: kid.friends
};
})
};
})
};
})
};
});
I wasn't sure what to do with the friends node. Should that be normalized into something more useful, or do you want to leave it alone?
This Fiddle demonstrates the technique.
I think we'd need to know more about your requirements. But several thing I see here are:
You declare tree and initialize it as an Array, then immediately reinitialize it as an
empty object
You are not creating the intermediate nodes here, such as tree[index] but just assuming
that they exist.
You are trying to assign the country[key] property of an object, using the dot-property
access.
Can you supply the countries structure and the grandfather's structure. And are they nested?
And finally, what would you like for the output format? The code above hints at it, but it's still a little fuzzy.
Edit
So are you trying to achieve a structure something like this?:
var countries = [
{
name: "Canada",
people: [
{
name: "Steve",
children: [
{
name: "Linda",
children: [
{
name: "Steve, Jr.",
friends: [
{
name: "Kriss"
}
//, more friends
]
}
//, more grandchildren
]
}
//, more parents
]
}
//, more grandparents
]
}
//, more countries
];
May be this jsfiddle can help you to get started?
And here is an example derived from your code.
Sounds like a homework, so I'll try to point you in the right direction. I think you are confusing objects and arrays. You could use a "country" object and a "person" object. A country object should have an array of person objects, as inhabitants. Person objects can have an array of person objects as descendants. Add a method like "addDescendant", which creates a new person under a person. From There you can build the structure as you like. Here is some pseudo code:
countries = [];
function Country(name){ this.name = name; this.population = [];}
function Person(kids){this.descendants = []; this.addDescendant = function(){...};
//loop from 1 to kids and add descendants as "new Person"
}
person = new Person(3);
country1 = new Country("MyCountry1");
// now add people to country1.population
countries.push(country1);
The final structure should look something like this:
countries = [
{ name: "country 1",
people: [{ name: "Steve"},
{name: "Clara", descendants: [{name: "Clara's daughter"},
{name: "Clara's son"}]
]}
},
{ name: "country 2",
people: [{}, {} ...]
}
];
How would you reference the models (Accord, CRV, Prius, etc) in this structure?
Is this a bad structure to be able to extract the makes...then use a make to get the models...then use the model to get the options?
var cars = [
{
"makes" : "Honda",
"models" : [
{'Accord' : ["2dr","4dr"]} ,
{'CRV' : ["2dr","Hatchback"]} ,
{'Pilot' : ["base","superDuper"] }
]
},
{
"makes" : "Toyota",
"models" : [
{'Prius' : ["green","reallyGreen"]} ,
{'Camry' : ["sporty","square"]} ,
{'Corolla' : ["cheap","superFly"] }
]
}
];
Thanks
The structure:
var cars = [
{ name: 'Honda', models: [
{ name: 'Accord', features: ['2dr', '4dr'] },
{ name: 'CRV', features: ['2dr', 'Hatchback'] },
{ name: 'Pilot', features: ['base', 'superDuper'] }
]},
{ name: 'Toyota', models: [
{ name: 'Prius', features: ['green', 'superGreen'] },
{ name: 'Camry', features: ['sporty', 'square'] },
{ name: 'Corolla', features: ['cheap', 'superFly'] }
]}
];
I wrote about the traversal and everything else here.
cars[0].models.Accord
cars[0].models.CRV
cars[0].models.Pilot (See olliej's answer)
Though, it may be easier to use the following access concept:
cars.Honda.Accord
cars.Toyota.Prius
...using...
var cars = {
Honda : {
Accord : ["2dr", "4dr"],
CRV : ["2dr", "Hatchback"],
Pilot : ["base", "superDuper"]
},
Toyota : {
Prius : ["green", "reallyGreen"],
Camry : ["sporty", "square"],
Corolla : ["cheap", "superFly"]
}
};
Jonathan's is correct, but he missed the additional level of Array's at the model level, so it should be
cars[0].models[0].Accord
cars[0].models[1].CRV
etc
I suspect you would find it easier to use a structure along the lines of:
var cars = [
{makes : "Honda",
models : {
Accord : ["2dr","4dr"],
CRV : ["2dr","Hatchback"],
Pilot: ["base","superDuper"]
}
},
{makes :"Toyota",
models : {
Prius : ["green","reallyGreen"],
Camry : ["sporty","square"],
Corolla : ["cheap","superFly"]
}
}];
In which the models array is replaced by an object (or associative array if you like)
[edit (olliej): tidying up code in second example]
You can traverse models with this code:
for (var i = 0, carslen = cars.length; i < carslen; i++) {
for (var j = 0, modelslen = cars[i].models.length; j < modelslen; j++) {
// do something with cars[i].models[j]
}
}
but I agree with Olliej about changing the structure of your JSON to his format.
If I were you, I wouldn't lump all your data into one big multidimensional array/object literal mess like that. I'd encapsulate each object and use methods to access the data. It'll mess with your brain a lot less.