In python, a dictionary of dictionaries can be created
mainDict = {}
mainDict[subDict][subDict_Key1]=[subDict_value1]
I want to create a similar dictionary of dictionaries or array of dictionaries in Javascript.
I have check multiple threads on SO but yet to find anyone.
I don't know the dictionaries yet, they will be added dynamically. For example I want to be able to create
var mainDict = {}
and then be able to add dict1,2,3... below
Dict1 = {name: sam, age:26, city:NY}
to mainDict so that I can iterate through mainDict and retrieve all dictionary with their respective keys and values
how do I do this in Javascript?
You first need to create the "sub-dictionary" before assigning values to it:
var mainDict = {}
mainDict[subDict] = {} // This was missing
mainDict[subDict][subDict_key1] = subDict_value1
Of course, if the values are static, this can be done in a more concise way:
var mainDict = {
dict1: {
name: 'sam',
age: 26,
city: 'NY'
},
dict2: {
name: 'joe',
age: 27,
city: 'LA'
}
}
console.log(mainDict.dict2.name) // joe
Then you can iterate through the inner dictionaries as you wish:
for (const key in mainDict) {
console.log(`${key} has name ${mainDict[key].name}`)
}
...or, alternatively:
for (const [key, subDict] of Object.entries(mainDict)) {
console.log(`${key} has name ${subDict.name}`)
}
Related
For example:
const array = [
{
name: JB,
age: 28,
dob: '12-17-1996'
}
{
name: Jamey,
age: 57
dob: '9-13-1965'
}
{
name: Jayla,
age:30,
dob: '11-18-1992'
}
]
How would I use the filter method (and without any arrow syntax involved) to remove one of these objects from the array and iterate the updated array in Javascript?
I tried it in a for loop but it just keeps giving me undefined.
You can use Array#filter to obtain all elements whose name do not match the name of the object you want removed.
const array=[{name:"JB",age:28,dob:"12-17-1996"},{name:"Jamey",age:57,dob:"9-13-1965"},{name:"Jayla",age:30,dob:"11-18-1992"}];
let remove = 'Jamey';
let filtered = array.filter(function(obj){
return obj.name !== remove;
});
for (const obj of filtered) console.log(obj);
I'm trying to render a dynamic list of fields from a JSON file.
Some fields have to go through this accountFieldMap object I created for key renaming purposes.
For example it finds the key userFirstName1 from the JSON and renders the value of it as firstName at the component.
const accountFieldMap = {
firstName: "userFirstName1",
lastName: "userLastName1",
ID: "userID",
location: `userLocation.city`,
};
The only issue is with the location field.
How can I let JavaScript know that it should render that city nested field and show it as location?
If I understand you correctly, location.city is a path to some value in object.
There are some libraries for this like lodash, which have inbuilt functions that can resolve that, but if you want to do it in vanilla js, you can do it by splitting this string by dot and going through that array to get a value.
const getByPath = (path, obj) => {
const splittedPath = path.split(".");
return splittedPath.reduce((acc, curr) => {
acc = obj[curr];
return acc;
}, obj)
}
So in this case if you have object like
const testObj = {
location: {city: "Kyiv"},
firstName: "Oleg"
}
It will return you "Kyiv" if you will pass into getByPath "location.city" as path. And it will also work in case if there is no nesting, so
getByPath("firstName", testObj)
will return you "Oleg"
you only have to map the array and create a new object;
import fileData from "../path/to/json";
const people = fileData.arrayName.map(person => ({
firstName: person.userFirstName1,
lastName: person.userLastName1,
ID: person.userID,
location: person.userLocation.city,
}));
Given the object:
const product = {
food: true,
clothes: false
}
is there a way to programmatically get the name of some key without using Object.keys or similar methods. Something like product.food.getKeyName() which would return a string 'food'. I find that I often have to add object key names to some constants object like:
const products = {
food: 'food',
clothes: 'clothes'
}
which is my primary motivation to figure out a programmatic solution.
Here's an example use case. I want to run over all keys of an object and have different behavior for each key:
Object.keys(product).map(key => {
if (key === 'food') {
// do something specific for food
}
})
but I don't want to write string literals like 'food'.
Thanks to #Enijar's tip indeed it is possible to programmatically retrieve object keys names using Javascript Proxy API as follows:
const product = {
food: true,
clothes: false
}
const proxy = new Proxy(product, {
get: function(originalObject, objectKey) {
if (originalObject.hasOwnProperty(objectKey)) {
return objectKey
}
throw new Error(`The field '${objectKey}' doesn't exist.`)
},
})
console.log(proxy.food) // logs 'food'
console.log(product.food) // logs 'true'
I'm really unsure what I'm doing here (new to JavaScript) but I know that I need the function to loop through each iteration of var schema and push it into var DB.
Here is my code so far:
var schema = ["id", "name", "age"]
function model(add, object, schema) {
var DB = {};
for (var key in schema) {
//i really don't know what code to put here that would take the
//conditions from model(below)and put it into var DB. This is
//where I am stuck.
}
return DB
}
model("add", {
id: 1,
name: "Joe",
age: 32 "}, schema)
The return I am trying for is: DB //[{id: 1, name: "Joe", age: 32}]
Assuming what you're trying to do is filter an input object down to a predefined schema of keys: you're almost there! Your loop should attempt to find the keys from schema in the input object and add them to your DB object:
function model(add, object, schema) {
var DB = {};
for (var key in schema) {
if (key in object) {
DB[key] = object[key];
}
}
return DB;
}
(As an aside, you might want to re-consider the variable name object as it's a built-in keyword.)
Came across the concept of creating new object using spread syntax as below
const human = { age: 20 };
const john = { ...human };
john.age = 10;
console.log(human.age); // 20
console.log(john.age); // 10
As shown above human object get to retain it's original value. Now have a look at below code:
const human = { age: 20, cars: ["toyota", "honda"] };
const john = { ...human };
john.cars[1] = "camero";
console.log(human.cars); // ["toyota", "camero"]
console.log(john.cars); // ["toyota", "camero"]
Can anyone explain to me why the above scenario happened? Why human's cars object get changed? It looks to me that it's very likely for developer to make mistakes without understanding how to avoid the inconsistent behaviour
The object human only contains a reference to the array which contains ["toyota", "honda"]. When you duplicate the object using the spread operator, you also duplicate the reference, which means that john has an identical reference and therefore john.cars is the same array as human.cars.
Because of this, if you modify john.cars, you also modify human.cars because they are the same array. If you want to clone an array you can also do this using the spread operator:
const human = { age: 20, cars: ["toyota", "honda"] };
const john = { ...human };
john.cars = [ ... human.cars ];
john.cars[1] = "camero";
console.log(human.cars); // ["toyota", "honda"]
console.log(john.cars); // ["toyota", "camero"]
You will also see this type of behaviour if you clone an object that has properties which are objects:
const human = { name: { first: "John", last: "Jackson" } };
const human2 = { ... human };
human2.name.first = "Ellen";
console.log(human.name.first); // Ellen
That's because the spread operator only copies a reference to the name object, not the name object itself. Therefore, modifying one modifies the other because they are the same object. This is referred to as shallow cloning. If you want to avoid this confusion, you need to perform a deep clone.
The easiest way to do this is to convert to JSON and then convert back:
const human = { name: { first: "John", last: "Jackson" } };
const human2 = JSON.parse(JSON.stringify(human));
human2.name.first = "Ellen";
console.log(human.name.first); // John
console.log(human2.name.first); // Ellen