I have to return Greg and Joe from this array of objects.
I am looping through the array and if the master is Emily I want to alert() Greg and Joe, review.name.
let list = [
{
master: "Leo",
review: [{
name: 'Bob',
stars: 2
},
{
name: 'Elly',
stars: 4
},
]
},
{
master: "Emily",
review: [{
name: 'Greg',
stars: 3
},
{
name: 'Joe',
stars: 2
},
]
},
]
for (let i = 0; i < list.length; i++) {
if (list[i].master === 'Emily') {
alert(list[i].review.name)
}
}
It doesn't alert anything.
That is because review is an array of objects & you need to pass index. In this demo passing 0 to get the first object. You again loop review and get the name from each object
let list = [
{
master: "Leo",
review: [{
name: 'Bob',
stars: 2
},
{
name: 'Elly',
stars: 4
},
]
},
{
master: "Emily",
review: [{
name: 'Greg',
stars: 3
},
{
name: 'Joe',
stars: 2
},
]
},
]
for (let i = 0; i < list.length; i++) {
if (list[i].master === 'Emily') {
alert(list[i].review[0].name)
}
}
review is an array of objects. We could one-line this like so, but I'll explain what we're doing:
alert(
list.find(e => e.master === "Emily").review
.map(e => e.name).join(', ')
)
list is an array, which has a find prototype. In the find method, we pass a function that returns true or false. We can decide what we're trying to find. In this case, we're trying to find the entry where the master property is "Emily". Having found what we're looking for, we can use map to loop through the entry's review property, and return an array of names which we finally stick together using join.
Another approach would be to use 2 loops:
for (let i = 0; i < list.length; i++) {
if (list[i].master === 'Emily') {
let names = [];
for (let j = 0; j < list[i].review.length; j++) {
names.push(list[i].review[j].name);
}
alert(names.join(', '));
}
}
Keep in mind that the first approach will throw an error if no entry with master property set to "Emily" can be found.
You can do:
const list = [{master: "Leo",review: [{name: 'Bob',stars: 2},{name: 'Elly',stars: 4},]},{master: "Emily",review: [{name: 'Greg',stars: 3},{name: 'Joe',stars: 2},]}]
list.forEach((o, i) => {
if (o.master === 'Emily') {
list[i].review.forEach(u => console.log(u.name));
}
});
Related
First time posting on here and was hoping to get some help I can't seem to figure out how to do this problem. It's basically to create a function that receives an array of objects that returns a new object.
For some reason, push won't go through and returns the error property of push is undefined.
const organizeInstructors = function(instructors) {
let output = {}; // so the obvious which is to create the object
for (let i = 0; i < instructors.length; i++) {
if (!output[instructors[course]]) {
output[instructors[course]] = instructors[course];
} else {
output[instructors[course]].push(instructors[name]);
}
}
return output;
};
console.log(organizeInstructors([{
name: "Samuel",
course: "iOS"
},
{
name: "Victoria",
course: "Web"
},
{
name: "Karim",
course: "Web"
},
{
name: "Donald",
course: "Web"
}
]));
expected output
{
iOS: ["Samuel"],
Web: ["Victoria", "Karim", "Donald"]
}
Thanks for any advice or hints you guys can give
Looks like you were getting a bit confused iterating over arrays vs keying into objects.
let organizeInstructors = function(instructors) {
let output = {}; // so the obvious which is to create the object
for(let i = 0; i < instructors.length; i++) {
const instructor = instructors[i]
if(!output[instructor.course]) {
output[instructor.course] = []
}
output[instructor.course].push(instructor.name)
}
return output;
}
console.log(organizeInstructors([
{name: "Samuel", course: "iOS"},
{name: "Victoria", course: "Web"},
{name: "Karim", course: "Web"},
{name: "Donald", course: "Web"}
]))
Adding the const instructor makes it much easier to read as well
This uses the Array.prototype.reduce method.
Please note that this will not check if the value is already present in the course array and will just blindly add in. This could mean that you get multiple instances of the same name in the same course.
const organizeInstructors = function(instructors) {
return instructors.reduce((cumulative, current) => {
// if we don't have a course in cumulative object, add it.
if (!cumulative[current.course]) cumulative[current.course] = [];
// add in the current name.
cumulative[current.course].push(current.name);
// return the cumulative object for the next iteration.
return cumulative;
}, {});
}
console.log(organizeInstructors([{
name: "Samuel",
course: "iOS"
},
{
name: "Victoria",
course: "Web"
},
{
name: "Karim",
course: "Web"
},
{
name: "Donald",
course: "Web"
}
]));
Using reduce
data = [ { name: "Samuel", course: "iOS" }, { name: "Victoria", course: "Web" }, { name: "Karim", course: "Web" }, { name: "Donald", course: "Web" }, ];
getObj = (data) =>
data.reduce(
(r, c) => (
!r[c.course] // checks if accumulator doesn't have c.course as key
? ((r[c.course] = []), r[c.course].push(c.name)) // then make an array that corresponds the key then push c.name
: r[c.course].push(c.name), // else push c.name to the corresponding array
r
),
{}
);
console.log(getObj(data));
For my scenario, I need to push elements to an addresses array which contains objects. I'm working with vue.js.
My current working function is:
propagateCustomerInfo(selectedOption, id){
// Propagate addresses
this.addresses = selectedOption.addresses
// Propagate contact's addresses
for (var i = selectedOption.contacts.length - 1; i >= 0; i--) {
for (var j = selectedOption.contacts[i].addresses.length - 1; j >= 0; j--) {
let address = selectedOption.contacts[i].addresses[j]
address.contact = selectedOption.contacts[i]
this.addresses.push(address)
}
}
},
the selectedOption object has the below structure:
{
addresses: [
{
id: 0,
street: 'My street'
},
{...}
],
contacts: [
{
id: 0,
name: 'Lorem Ipsum',
addresses: [
{
id: 0,
street: 'My street'
},
{...}
],
}
]
}
Besides pushing every contact's address object to this.addresses array I need to append the contact to the address itself for multiselect rendering purposes. That's why I'm doing address.contact = selectedOption.contacts[i]
I almost sure that this can be accomplished in a prettiest way with some mapping/reduce combination but I can't figure out how to do it.
Any help will be really appreciated.
Thanks!
if you want to combine all address in contact variable to addresses variable:
this.contacts.map(contact => this.addresses.push(...contact.addresses))
Edit.
to inject the contact.id and contact.name:
this.contacts.map(contact => {
let temp = []
contact.addresses.map(address => {
temp.push({
name: contact.name,
id: contact.id,
...address
})
})
this.addresses.push(...temp)
})
I have two arrays(arrayA & arrayB). I want to check if any of the items in arrayA allready exists in arrayB. if it doesn't I want to add it to arrayB(but that's not the problem). In the exampel I just want to console.log that I'm adding the item to array B.
First I thought this was a good idea:
for(var i = 0; i < arrayA.length; i++){
for (var j = 0; j < arrayB.length; j++) {
if(body[i].id == res[j].name){
console.log("The article allready exsists")
}
else{
console.log("Adding item to arrayB")
}
}
}
Then I realised that this wasn't a verry good way to do it because the array's are pretty big. Also the else-statement will be ran the number of times equal to the length of arrayA. Also It's a problem because the first time this will run the array length of arrayB will be zero and wont even reach the else-statement.
Is their any other ways to achive what I'm trying to do here?
You could use a hash table and a linear approach by iterating first arrayB and collect the name property and then iterate over arrayA and check if the id is in arrayB with the hash table. Add the information to arrayB if not exist.
var arrayA = [{ id: 1 }, { id: 3 }, { id: 4 }, { id: 6 }, { id: 7 }, { id: 9 }, { id: 12 }, { id: 35 }, { id: 22 }, { id: 11 }, { id: 34 }, { id: 90 }, { id: 2 }],
arrayB = [{ name: 1 }, { name: 7 }, { name: 8 }, { name: 19 }, { name: 25 }, { name: 41 }, { name: 35 }, ],
hashB = Object.create(null);
arrayB.forEach(function (b) {
hashB[b.name] = true;
});
arrayA.forEach(function (a) {
if (!hashB[a.id]) {
arrayB.push({ name: a.id });
hashB[a.id] = true;
}
});
console.log(arrayB);
.as-console-wrapper { max-height: 100% !important; top: 0; }
May be this could help. You donot need nested loops for achieving this.
var arrayA = [1,2,3,4,5,6];
var arrayB = [2,4,7,8];
for(var i = 0; i < arrayA.length; i++){
if(arrayB.indexOf(arrayA[i]) > -1){
console.log("The article allready exsists");
}
else{
console.log("Adding item to arrayB")
}
}
I have an array like this
$scope.dogs = [
{ id: 1, breed: 'German Shepherd' },
{ id: 2, breed: 'Collie' }
]
And a second array like this:
$scope.owners = [
{ name: 'Mary', breedowned: 'German Shepherd' },
{ name: 'Bill', breedowned: 'German Shepherd' },
{ name: 'Bob', breedowned: 'Collie' }
]
I want to push the list of owners into the list of dogs like so basically creating:
$scope.dogs = [
{ id: 1, breed: 'German Shepherd', owners: [...] }
]
I tried to use forEach and push the owners into the dogs array, but it does not work.
angular.forEach($scope.dogs, function (value, key) {
for (x = 0; x < $scope.owners.length; x++) {
if ($scope.owners[i].breedowned == value.breed) {
$scope.dogs[key].owners.push($scope.owners[i])
}
}
});
Thanks for any help!
If you don't want any form of dependency, just use Array.prototype.push.apply, this way:
Array.prototype.push.apply($scope.owners, $scope.dogs);
You didnt mention any errors, but I see an issue with you missing var in front of the x in the for loop, and also owners is not initialized in the dog object. Here's a consistent nested loop solution:
angular.forEach($scope.dogs, function (dog) {
angular.forEach($scope.owners, function (owner) {
if (owner.breedowned == dog.breed) {
dog.owners = dog.owners || []
dog.owners.push(owner)
}
})
})
Here a better solution that only goes through the owners array once and only through the dogs array once.
var tracker = $scope.owners.reduce(function(trackerObj, owner){
var breedowned = owner.breedowned;
trackerObj[breedowned] = trackerObj[breedowned] || [];
trackerObj[breedowned].push(owner);
return trackerObj;
}, {});
$scope.dogs.forEach(function(dog){
dog.owners = tracker[dog.breed];
});
i have this json:
var projects_array = [
{name:"proj1", category:"a", index:1},
{name:"proj2", category:"a", index:2},
{name:"proj3", category:"b", index:3},
{name:"proj4", category:"c", index:4}
];
I am displaying them in order with something like this:
for (var i = 0 ; i <proj_num; i++){
var numClass="p_"+projects_array[i].index;
var act="<li class='"+numClass+"'></li>";
$('#lookfor').append(act);
}
What i need now is to display first all the objects with the value "a" in the category attribute and then all the other objects in any order, i tried using .sort() in this way:\
function compare(obj){
if(obj.category == "a"){ return 1;}
else{return 0;}
}
obj.sort(compare);
But it does not worked because it kind of group all the objects of the category...
do you have any possible solution for this problem?
ps: I tried to simplify my code to make it understandable, i hope it be clear for you, thanks in advance
this will sort according to the important word first.
http://jsbin.com/umezet/12/edit
var projects_array = [
{
name: "proj1",
category: "action",
index: 1
}, {
name: "proj2",
category: "time",
index: 2
}, {
name: "proj3",
category: "buu",
index: 3
}, {
name: "proj3",
category: "time",
index: 3
}, {
name: "proj4",
category: "cooo",
index: 4
}, {
name: "proj3",
category: "#",
index: 3
}, {
name: "proj1",
category: "!",
index: 1
}, {
name: "proj2",
category: "%",
index: 2
}, {
name: "proj3",
category: "cooo",
index: 3
}, {
name: "proj4",
category: "*",
index: 4
}];
projects_array = projects_array.sort(
function (x, y)
{
if(x['category'] == 'time') return -1;
if(y['category'] == 'time') return 1;
if(x['category'] > y['category']) return 1;
if(x['category'] < y['category']) return -1;
return 0;
});
for(var i = 0; i < projects_array.length; i++)
{
$('body').append(projects_array[i]['category']);
}