How do I add a new element in a dictionary in JS? - javascript

I have this kind of dictionary:
INPUT
movies = {
'big' : {
actors : ['Elizabeth Perkins', 'Robert Loggia']
},
'forrest gump' : {
actors : ['Tom Hanks', 'Robin Wright', 'Gary Sinise']
},
'cast away' : {
actors : ['Helen Hunt', 'Paul Sanchez']
}
};
and I want to use this dictionary to get a different one. For example, I have to make a function called "moviesWithActors" that will received two arguments: "movies" and "actor". Actor could be "Tom Hanks", so when you find that he was on the movie, you don't add to the nested array, but if wasn't, you add.
OUTPUT
movies = {
'big' : {
actors : ['Elizabeth Perkins', 'Robert Loggia', 'Tom Hanks']
},
'forrest gump' : {
actors : ['Tom Hanks', 'Robin Wright', 'Gary Sinise']
},
'cast away' : {
actors : ['Helen Hunt', 'Paul Sanchez', 'Tom Hanks]
}
};
I do this:
for (const value of Object.values(newMovies)){
console.log(value.actors)
for (const act of value.actors){
//console.log(act)
if (act == actor) {
console.log("Ok, not add")
}else{
console.log("Here I have to add");
}
}
}
where "newMovies" is a copy of "movies" and "actor = "Tom Hanks" but I can't add to the array in actors: [ ... ]. Any suggestion? Can I use map() ?

As per the requirement what I understood is that there is an existing array of movies object and you want to assign a hero in those movies. We have to ignore if the passed hero name is already there for that movie else add that hero under that movie. If my understanding is correct, Here you go :
const movies = {
'big' : {
actors : ['Elizabeth Perkins', 'Robert Loggia']
},
'forrest gump' : {
actors : ['Tom Hanks', 'Robin Wright', 'Gary Sinise']
},
'cast away' : {
actors : ['Helen Hunt', 'Paul Sanchez']
}
};
function updateMoviesList(obj, heroName) {
Object.keys(obj).forEach(key => {
if (!obj[key].actors.includes(heroName)) {
obj[key].actors.push(heroName)
}
})
return obj;
}
console.log(updateMoviesList(movies, 'Tom Hanks'));

You can use Push()
Like this from docs
let sports = ['soccer', 'baseball']
let total = sports.push('football', 'swimming')
console.log(sports) // ['soccer', 'baseball', 'football', 'swimming']
console.log(total.length) // 4
To access array inside dictionary you have first to access it
movies['big']['actors'].push('New Actor')
For not be "hard coded", if you do this?
let actor = 'Tom Hanks'
for (const value of Object.values(newMovies)){
for (const act of value.actors){
if (value.actors.includes(actor)) { //Here you check if actor contains in array
console.log("Ok, not add")
}else{
console.log("Here I have to add");
value.actors.push(actor) //if not push to array
}
}
}

I was suggested to use map instead and the class Object...
function actorInMovies(movies, actor) {
let mappedObject = { ...movies};
Object.entries(movies).map(movie => {
const movieName = movie[0];
const actors = movie[1].actors;
if (!actors.includes(actor))
actors.push(actor);
mappedObject = {
...mappedObject,
[movieName]: { actors }
};
});
return mappedObject
}
function main(){
const movies = {
'big' : {
actors : ['Elizabeth Perkins', 'Robert Loggia']
},
'forrest gump' : {
actors : ['Tom Hanks', 'Robin Wright', 'Gary Sinise']
},
'cast away' : {
actors : ['Helen Hunt', 'Paul Sanchez']
}
};
const actor = 'Tom Hanks';
console.log(actorInMovies(movies, actor))
}
main();

Related

How do you check if value exist in object of object's array?

I want to know which logic i should use to check every object's array of parent object contained in grand parent object
Hi guys i want to check if this value for example : "127.0.0.1" exists in this object (MyObject has like 2k objects in it)
{
"name" : MyObject
"value": [
{
"name" : "Object1",
"properties":{
"address" : [
"13.65.25.19/32",
"13.66.60.119/32",
]
}
},
{
"name" : "Object2",
"properties":{
"address" : [
"13.65.25.19/32",
"127.0.0.1",
]
}
}
]
}
Btw does include() needs to match the whole string or for example if 127.0.0.1 is like this in my object 127.0.0.1/32, i can still retrieve it even if there is a ip range ?
Your data is structured quite specifically, so you can write a custom method which you can call over and over again. It will check for a
const obj = {
name: 'MyObject',
value: [
{
name: 'Object1',
properties: {
address: ['13.65.25.19/32', '13.66.60.119/32'],
},
},
{
name: 'Object2',
properties: {
address: ['13.65.25.19/32', '127.0.0.1'],
},
},
],
};
const address = '127.0.0.1';
const includesAddress = (address) => {
for (const val of obj.value) {
if (val.properties.address.some((a) => address === a)) return true;
}
return false;
};
console.log(includesAddress(address));
Array.flatMap implementation
const obj = {
name: 'MyObject',
value: [
{
name: 'Object1',
properties: {
address: ['13.65.25.19/32', '13.66.60.119/32'],
},
},
{
name: 'Object2',
properties: {
address: ['13.65.25.19/32', '127.0.0.1'],
},
},
],
};
const address = '127.0.0.1';
const output = obj.value.flatMap(item => item.properties.address).includes(address);
console.log(output);
If you want check if the partial ip addess is included in the list, you should make use of a regex implementation.
Sample Implementation
const obj = {
name: 'MyObject',
value: [
{
name: 'Object1',
properties: {
address: ['13.65.25.19/32', '13.66.60.119/32'],
},
},
{
name: 'Object2',
properties: {
address: ['13.65.25.19/32', '127.0.0.1'],
},
},
],
};
const address = '13.65.25.19';
const regex = new RegExp(address, 'i')
const output = obj.value.flatMap(item => item.properties.address).filter(x => regex.test(x)).length > 0;
console.log(output);

Array missing in react redux reducer

i am trying to check my inner array id same as dispatched id, table example
{
_id :1,
name: sagar elias jacky
Amenities :[{ id: 100, title : hi },{ id: 101, title : hallo } ]
}
checking dispatched id exit or not using map,
return { ...state,
items : {...state.items,
Amenities : { ...state.items.Amenities
.map(x=> x._id === action.dispatchedID ? {...x,deleting: true} : x ) }}}
but it will return with non array Amenities, like
Amenities:
0: { id: 100, title : hi },
1: { id: 101, title : hallo }
i want this to
Amenities:Array(2)
0: { id: 100, title : hi },
1: { id: 101, title : hallo }
When you spread an array inside {}, it creates an object with indexes of array as keys
const array = [{a:1}, {a:2}]
console.log({...array})
So, change
Amenities : { ...state.items.Amenities
.map(x=> x._id === action.dispatchedID ? {...x,deleting: true} : x ) }
to:
Amenities : [ ...state.items.Amenities
.map(x=> x._id === action.dispatchedID ? {...x,deleting: true} : x ) ]

Generate a new array with count of property values

I have an array in my state :
projects: [
{ title: 'todo 1', person: 'Sam', status: 'ongoing'},
{ title: 'project', person: 'Jack', status: 'complete' },
{ title: 'Design video', person: 'Tim', status: 'complete' },
{ title: 'Create a forum', person: 'Jade', status: 'overdue' },
{ title: 'application', person: 'Jade', status: 'ongoing'},],
From this array (projects), I would like to generate a new array with Javascript and to get this result :
totalByPersonAndStatus : [
{person : 'Sam', complete: 0, ongoing: 1, overdue: 0 },
{person : 'Jack', complete: 1, ongoing: 0, overdue: 0 },
{person : 'Tim', complete: 1, ongoing: 0, overdue: 0 },
{person : 'Jade', complete: 0, ongoing: 1, overdue: 1 },]
I tried it
totalProjectsByPersonAndStatus: state => {
state.projects.forEach(name => {
state. totalByPersonAndStatus["name"] = name.person;
});
return state. totalByPersonAndStatus;
The problem, if a make a console.log(this.totalByPersonAndStatus) I have an object with only the data of projects.name [name: "Jade", __ob__: Observer]
Can you help me ?
Thank you
You can use reduce
let projects =[{title:'todo1',person:'Sam',status:'ongoing'},{title:'project',person:'Jack',status:'complete'},{title:'Designvideo',person:'Tim',status:'complete'},{title:'Createaforum',person:'Jade',status:'overdue'},{title:'application',person:'Jade',status:'ongoing'},]
let desired = projects.reduce((output,{person,status}) => {
if( output[person] ){
output[person][status]++
} else {
output[person] = {
person,
complete: Number(status==='complete'),
ongoing: Number(status==='ongoing'),
overdue: Number(status==='overdue')
}
}
return output;
},{})
console.log(Object.values(desired))
Create a new Set for people and statuses by iterating through the projects, a set has only unique values so sets are a convenience, iterate through your people set creating a new object with all the statuses initialized to 0, then iterate over the projects to increment the various statuses that apply. This method allows any number of new statuses to be added without changing the code - dynamic.
var people = new Set();
var status = new Set();
projects.forEach((p)=>{
people.add(p.person);
status.add(p.status);
});
var totalByPersonAndStatus = [];
people.forEach((person)=>{
let peeps = { "person": person };
status.forEach((stat)=>{
peeps[stat] = 0;
});
projects.forEach((project)=>{
if (project.person === person) { peeps[project.status]++; }
});
totalByPersonAndStatus.push(peeps);
});
You could use reduce and destructuring like this:
const projects=[{title:'todo 1',person:'Sam',status:'ongoing'},{title:'project',person:'Jack',status:'complete'},{title:'Design video',person:'Tim',status:'complete'},{title:'Create a forum',person:'Jade',status:'overdue'},{title:'application',person:'Jade',status:'ongoing'}]
const merged = projects.reduce((acc,{person,status})=>{
acc[person] = acc[person] || { person, ongoing:0, complete:0, overdue:0}
acc[person][status]++;
return acc;
},{})
console.log(Object.values(merged))
The goal is create an object merged with each person as key and then increment based on the statuses:
{
"Sam": {
"person": "Sam",
"ongoing": 1,
"complete": 0,
"overdue": 0
},
"Jack": {
}
...
}
Then use Object.values, to get the final array.
You could make it a one-liner:
const projects=[{title:'todo 1',person:'Sam',status:'ongoing'},{title:'project',person:'Jack',status:'complete'},{title:'Design video',person:'Tim',status:'complete'},{title:'Create a forum',person:'Jade',status:'overdue'},{title:'application',person:'Jade',status:'ongoing'}],
output = Object.values(projects.reduce((a,{person,status})=>
((a[person] = a[person] || {person,ongoing:0,complete:0,overdue:0})[status]++,a),{}))
console.log(output)

Javascript object : select the whole object that has known key : value pair

I'm confused with a complex json object, in the example bellow, how can I store in a variable the whole object that has entreprise : 'microsoft'.
clientList = {
id-1111 : {
entreprise : 'facebook',
president : 'Mark',
},
id-2222 : {
entreprise : 'microsoft',
president : 'Bill',
},
id-3333 : {
entreprise : 'apple',
president : 'Tim'
}
}
I dynamicly get, for axample, 'Microsoft', and I would like to obtain as output :
{
entreprise : 'microsoft',
president : 'Bill'
}
I know it is a basic question, but I'm struggling with that for hours.
Thanks for your help.
You can use find to find a single item from a list.
var clientList = {
"id-1111": {
entreprise : 'facebook',
president : 'Mark',
},
"id-2222" : {
entreprise : 'microsoft',
president : 'Bill',
},
"id-3333" : {
entreprise : 'apple',
president : 'Tim'
}
};
var result = Object.values(clientList).find(x => x.entreprise == "microsoft");
console.log(result);
To find all objects with a paticular enterprise, use Array.filter:
const clientList = {
"id-1111" : {
entreprise : 'facebook',
president : 'Mark',
},
"id-2222" : {
entreprise : 'microsoft',
president : 'Bill',
},
"id-3333" : {
entreprise : 'apple',
president : 'Tim'
}
};
function findClientsByEnterprise(enterprise) {
return Object.values(clientList).filter( i => i.entreprise === enterprise);
}
console.log(findClientsByEnterprise("microsoft"))
Your object has broken. Use quote in your object key.
clientList = {
'id-1111' : {
entreprise : 'facebook',
president : 'Mark',
},
'id-2222' : {
entreprise : 'microsoft',
president : 'Bill',
},
'id-3333' : {
entreprise : 'apple',
president : 'Tim'
}
};
function objectSearch(key, value,obj){
for(o in obj){
if(obj[o][key] == value){
return obj[o];
}
}
return {};
}
console.log(objectSearch('entreprise','microsoft',clientList));
if the enterprise can be used as a unique ID, you could just use it as such:
'microsft': {
enterprise: 'microsoft',
president: 'Bill'
}
but as a general rule, it is not a great practice to do this. So maintaining a structure with a list of objects with unique ID's and using find would be the best solution and best practice:
clientList = [
{
id: 'id-1111',
entreprise : 'facebook',
president : 'Mark',
},
{
id: 'id-2222',
entreprise : 'microsoft',
president : 'Bill',
},
{
id: 'id-3333',
entreprise : 'apple',
president : 'Tim'
}
}
const result = clientList.find(clientObj => clientObj.enterprise === "microsoft");

Populating arrays after their definition

I have a ul containing li's which contain names of different recipe ingredients for a recipe page. I'm trying to get those ingredients and store them into a JavaScript array within an object. I already know the title of the recipe so I put that right into the object property title, but I don't know how many ingredients there will be for each recipe. Here is what I have:
var recipeobj = {
title: $('h3.title').val(),
ingredients: [
ingredient,
optional
]
}
$.each($('ul.ingredients > li > h4'), function (index, ingredient) {
recipeobj.ingredients[index].ingredient = $(ingredient).html();
recipeobj.ingredients[index].optional = false;
})
If I try to do console.log(recipeobj.ingredients) I just get the error Uncaught ReferenceError: ingredient is not defined
No doubt this is simple, I just rarely need to use arrays in JavaScript so have little experience with them.
Open your console and run it
var recipeobj = {
title: $('h3.title').html(),
// ingredients is empty for now
ingredients: []
};
$.each($('ul.ingredients > li > h4'), function(index, ingredient) {
// Get the name
var name = $(ingredient).html(),
// Find out if it is 'optional'(using a class here)
optional = $(ingredient).hasClass('optional');
// Push a new ingredient into the array
recipeobj.ingredients.push({ name: name, optional: optional });
});
console.log(recipeobj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3 class="title">Pork and beans</h3>
<ul class="ingredients">
<li>
<h4>Pork</h4>
</li>
<li>
<h4>Beans</h4>
</li>
<li>
<h4 class="optional">Salt*</h4>
</li>
</ul>
This should output:
{
"title": "Pork and beans",
"ingredients": [
{ name : "Pork", optional : false },
{ name : "Beans", optional : false },
{ name : "Salt*", optional : true}
]
}
var rObj = {
title: $('h3.title').val(),
ingredients: [
'source cream',
'cheese',
'chopped meat'
],
optional: true
};
accessing
var rItem = rObj.ingredients[1];
or you want
var rObj = {
title: $('h3.title').val(),
ingredients: {
ingredient_list: ['one','two','three'],
optional: true
}
};
accessing
var rItem = rObj.ingredients.ingredient_list[1];
The structure you are attempting to use looks like the structure should be like
var rObj = {
title: $('h3.title').val(),
things: [{
ingredient: 'source cream',
optional: true
},
{
ingredient: 'cheese',
optional: false
}]
};
accessing
var ingred = rObj.things[1].ingredient;
var rObj = {
title: $('h3.title').val(),
ingredients : []
};
you can add ingredients:
$.each($('ul.ingredients > li > h4'), function (index, ingredient) {
rObj.ingredients.push({ingredient: $(ingredient).html(), optional :false})
})

Categories

Resources