I have a object, in that object I have other objects (objectseption). Now I want to be able to delete one of those objects (the objects within the main object) from a ID value given. I'll show you what I mean:
object {
1 : {
id: 1,
name: john
},
2: {
id: 3,
name: sam
},
3: {
id: 5,
name: ollie
},
4: {
id: 12,
name: nathan
}
}
Now let's say that I want to delete/remove Sam from the object, but all I have is Sam's ID. This is where I'm stuck. How do I remove Sam only having his ID (which is 3).
I'm quite new to javascript, and usually rely heavily on frameworks to complete a project - so when it comes to these simple things I get quite stuck!
Any Help would be greatly appreciated!
Iterate the objects properties, check, and remove:
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key].id == 3) {
delete obj[key];
}
}
}
Related
I am trying to figure out the best way to map an objects id property that is within a multi-dimension array to object values that are within another array that share the same id.
As an example i have an array of genre_ids like so:
0: {id: 1, name: 'sci-fi'},
1: {id: 2, name 'comedy'},
2: {id: 3, name: 'action'}
And an array of tv_show_genre_ids which looks like:
0: {name: ..., genre_ids: [1, 4, 9]},
1: {name: ..., genre_ids: [2, 3, 4]},
I was trying to figure out the best way to retrieve a list of the genres name by its id.
I have managed to create a working solution so far but it feels incredibly dirty as i am performing multiple nested loops and i wasn't sure if there is a cleaner more declarative approach to my solution
Here is my approach which assumes i already have a list of genre ids and names (accessed within this.genres.
this.http.get('https://api.com/shows')
.subscribe((res: array <any> ) => {
this.shows = res.results;
this.shows.forEach(show => {
show.genre_names = '';
show.genre_ids.forEach(id => {
for (const [i, v] of this.genres.entries()) {
if (id == v.id) {
if (this.genres[i] && this.genres[i].name) {
if (show.genre_names === '') {
show.genre_names = this.genres[i].name
} else {
show.genre_names += `, ${this.genres[i].name}`;
}
}
}
}
})
});
});
Is there a better way of doing this as i seem to come across this type of problem quite often when trying to map ids from one object to another within multi-dimension arrays.
Any guidance would be greatly appreciated.
EDIT:
Here is an example of the Genre Data from the API af:
0: {id: 10759, name: "Action & Adventure"}
1: {id: 16, name: "Animation"}
And here is an example of the show data from the API:
0:
backdrop_path: "/ok1YiumqOCYzUmuTktnupOQOvV5.jpg"
first_air_date: "2004-05-10"
genre_ids: (2) [16, 35]
id: 100
name: "I Am Not an Animal"
origin_country: ["GB"]
original_language: "en"
original_name: "I Am Not an Animal"
overview: "I Am Not An Animal is an animated comedy series about the only six talking animals in the world, whose cosseted existence in a vivisection unit is turned upside down when they are liberated by animal rights activists."
popularity: 10.709
poster_path: "/nMhv6jG5dtLdW7rgguYWvpbk0YN.jpg"
vote_average: 9.5
vote_count: 341
I want to add a new property to the show object named genre_names which gets the genre name via the genre response.
Your best bet is to first convert your genres into a Map or an object to use as a lookup:
const genreLookup = new Map();
this.genres.forEach(genre => genreLookup.set(genre.id, genre));
Now when you process an array of shows, you don't have to loop through the genres multiple times:
this.shows.forEach(show => {
show.genre_names = show.genre_ids
.filter(id => genreLookup.has(id))
.map(id => genreLookup.get(id).name)
.join(', ');
});
I'm currently working on a small application where I have to loop through an enormous array of objects. What would be the most efficient method to perform this?
var array = [
{
id: "1",
name: "Alpha"
},
{
id: "2",
name: "Beta"
},
...
];
I'd like to get each object where name equals "Alpha". I'm currently using a simple if statement to filter the objects with a different name value out, but I wonder if there's a more efficient way to do this, performance-wise.
It's worth to mention that I'll push the matching results into a new array.
No, there is no more efficient way.
The alternative is to build and maintain some kind of internal data structure which allows you to find the desired elements faster. As usual, the trade off is between the work involved in maintaining such a structure vs the time it saves you.
I don't have any way about which I would know it's more effective.
But if you had your objects ordered by name you could stop your search imideatly upon reaching an object whose name is not equal to "Alpha".
To find the first object you're looking for you can use binary search and from this Object you go up and down until at both ends you reach an object which isn't named "Alpha" or the end of array.
This is only a way of optimizing and will require time to sort the array and also will take more time when adding an element.
There's a JavaScript function exactly for this kind of task. Filter
From the Docs
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Here is a small example by code for getting all element from array which has a certain 'name' field:
const arr = [
{name: 'Abc'},
{name: 'Xyz'},
{name: 'Lmn'},
{name: 'Xyz'},
{name: 'Xyz'}
];
let response = findByName('Xyz');
console.log(response);
function findByName (name) {
return arr.filter((element) => {
return element.name = name;
});
}
If you need more than one time a collection with a given name, you could use an object with the names as hashes and have instantly access to the items.
var array = [{ id: "1", name: "Alpha" }, { id: "2", name: "Beta" }, { id: "3", name: "Beta" }, { id: "4", name: "Gamma" }, { id: "5", name: "Beta" }, { id: "2", name: "Alpha" }],
hash = Object.create(null);
array.forEach(function (a) {
if (!hash[a.name]) {
hash[a.name] = [];
}
hash[a.name].push(a);
});
console.log(hash);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have this array of objects
[ { id: '573267d06b2957ab24c54d59' },
{ id: '573267d06b2957ab24c54d5a' },
{ id: '573267d06b2957ab24c54d5b' },
{ id: '573267d06b2957ab24c54d5c' },
{ id: '573267d06b2957ab24c54d5d' }
]
I wish to convert it to the following in NodeJs
[ '573267d06b2957ab24c54d59',
'573267d06b2957ab24c54d5a',
'573267d06b2957ab24c54d5b',
'573267d06b2957ab24c54d5c',
'573267d06b2957ab24c54d5d'
]
It seems like it should be easy given the right library/package, but I am struggling to find the right wording to "flatten" the array into the IDs of the contained objects.
Say your array of objects is called arr, just do this:
var arrayOfStrings = arr.map(function(obj) {
return obj.id;
});
map will iterate over the array and create a new array based on how you define your function. In this case we return the value of the id key in each case to build out the desired array of ids.
I'm trying to do a matching between an object of objects (A) and an array of objects (B).
Each object in the object of objects has a PID. Each object in the array of objects has a PID. I am trying to match A and B so I can get the occupation from A, and then append the occupation to each object in B. So, I am trying to get PID and Occupation into one. Can this even be done?
So, here's what A might look like:
{
emp1: {
PID: 2430
Occupation: Welder
},
emp2: {
PID: 432,
Occupation: Electrician
}
}
and B:
[
{
PID: 432
},
{
PID: 2430
}
]
Can this be easily done using something like lodash library?
You would need to run a loop inside loop to match elements from B to A (or other way round) which is quite expensive. It would have been much easier if you could change structure of, let's say, A.
A = {
2430: {
name: "John",
occupation: "Welder"
},
432: {
name: "John",
occupation: "Electrician"
}
}
Then you can access data in A like this: A[2430]
Then your code could look like that:
B = B.map(function(el) {
return {
PID: el.PID,
occupation: A[el.PID].occupation
}
});
console.log(B);
So you have just one loop. Also you benefit from much faster access to data from A in the future.
I have a big json object I am using to control a cascading select list that I am trying to filter down to prepare for sending to the server.
The structure looks something like this -
Accounts[{name:account1, id:1, selected:false, schools:[{name:school1, id:2,selected:true}]}]
(With multiple accounts with multiple schools in each, keeping it simple for example purposes)
What I am trying to do is put it through some maps/filters and achieve an array of ids of schools that have the key of selected = true. So my attempt is to filter down by first all schools, then by schools that have selected true, then just the id's of those schools.
So here is my attempt -
$scope.schooIDsForSave = $scope.accountTreeHere.filter( function(obj){
return obj.schools;
}).filter( function(obj){
return obj.selected;
}).map(function(obj){
return obj.id;
});
This is only returning 1 ID so I'm getting something wrong here. I think I have something wrong with my usage of map/filter as I am still vey new to it. Any insight to point me in the right direction would be much appreciated! Thanks for reading.
Given structure
var schools = [{
name: 'account1',
id: 1,
selected: false,
schools: [{
name: 'school1',
id: 2,
selected: true
}]
}, {
name: 'account2',
id: 2,
selected: false,
schools: [{
name: 'school2',
id: 3,
selected: false
}]
}];
Try
var ids = schools.map(function(v) {
return v.schools;
}).reduce(function(a, b) {
return a.concat(b);
}).filter(function(v) {
return v.selected;
}).map(function(v) {
return v.id;
});