3

i have an array of objects, in which each object could have an array of objects inside.

var mylist = [
 {
 "email" : null, 
 "school" : "schoolA",
 "courses": [
 {
 "name" : 'ABC', 
 "type" : "chemistry"
 }, 
 {
 "name" : 'XYZ',
 "type": "math"
 }
 ]
 }, 
 {
 "email" : null,
 "school": "schoolB"
 }
];

i want to return course name if one of the course type is chemistry. The course types are unique and even if they are some duplicates, we return the first one.

var result = mylist.some(function (el) {
 el.courses && el.courses.some(function(u) {
 if (u.type === 'chemistry') {
 return u.name;
 }; 
 })
 });
console.log('outcome:', result); 

my code is not working at this stage.

asked May 7, 2018 at 9:31
1
  • You must use the find function to find the right course object and then return the name of the found course. The function some only returns a boolean value with the value of the given predicate. Commented May 7, 2018 at 9:35

2 Answers 2

3

The some callback should return a truthy or falsy value, which tells some whether to keep going (true = stop), and some returns a boolean, not a callback return value.

Probably simplest in this case just to assign directly to result:

var result;
mylist.some(function(el) {
 return (el.courses || []).some(function(course) {
 if (course.type === "chemistry") {
 result = course.name;
 return true;
 }
 return false;
 });
});

Live Example:

var mylist = [
 {
 "email" : null, 
 "school" : "schoolA",
 "courses": [
 {
 "name" : 'ABC', 
 "type" : "chemistry"
 }, 
 {
 "name" : 'XYZ',
 "type": "math"
 }
 ]
 }, 
 {
 "email" : null,
 "school": "schoolB"
 }
];
var result;
mylist.some(function(el) {
 return (el.courses || []).some(function(course) {
 if (course.type === "chemistry") {
 result = course.name;
 return true;
 }
 return false;
 });
});
console.log(result);


I stuck to ES5 syntax since you didn't use any ES2015+ in your question, but in ES2015+, simplest probably to use nested for-of loops:

let result;
outer: for (const el of mylist) {
 for (const course of el.courses || []) {
 if (course.type === "chemistry") {
 result = course.name;
 break outer;
 }
 }
}

Live Example:

const mylist = [
 {
 "email" : null, 
 "school" : "schoolA",
 "courses": [
 {
 "name" : 'ABC', 
 "type" : "chemistry"
 }, 
 {
 "name" : 'XYZ',
 "type": "math"
 }
 ]
 }, 
 {
 "email" : null,
 "school": "schoolB"
 }
];
let result;
outer: for (const el of mylist) {
 for (const course of el.courses || []) {
 if (course.type === "chemistry") {
 result = course.name;
 break outer;
 }
 }
}
console.log(result);

answered May 7, 2018 at 9:37
Sign up to request clarification or add additional context in comments.

Comments

2

You could use reduce() method to iterate through each object in array and then find() method to find if some course matches type.

var mylist = [{"email":null,"school":"schoolA","courses":[{"name":"ABC","type":"chemistry"},{"name":"XYZ","type":"math"}]},{"email":null,"school":"schoolB"}]
const course = mylist.reduce((r, {courses}) => {
 if (courses && !r) {
 const course = courses.find(({type}) => type == 'chemistry');
 if (course) r = course.name;
 }
 return r;
}, null)
console.log(course)

answered May 7, 2018 at 9:40

2 Comments

Yes, reduce keeps going but at least find doesn't starts.
Yeah, it's a really quick callback for the remaining elements. :-)

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.