2

Not sure I can do this but what I'm trying to do is create a new array by searching through some JSON data to find a key and taking the whole object into the new array if the key is found. Below is a sample of the data I am using.

{
  "students": {
    "AB10001": {
      "campus": "cda",
      "subjects": ["history", "english"],
    }
    "AB10002": {
      "campus": "asd",
      "subjects": ["maths"],
    }
    "AB10003": {
      "campus": "asd",
      "subjects": ["english"],
    }
    "AB10004": {
      "campus": "asd",
      "subjects": ["history"],
    }
    "AB10005": {
      "campus": "cda",
      "subjects": ["maths", "science"],
    }
    "AB10006": {
      "campus": "asd",
      "subjects": ["science"],
    }
    "AB10007": {
      "campus": "cda",
      "subjects": ["science"],
    }
    "AB10008": {
      "campus": "asd",
      "subjects": ["science", "history"],
    }
    "AB10009": {
      "campus": "cda",
      "subjects": ["history"],
    }
    "AB10010": {
      "campus": "cda",
      "subjects": ["history", "maths"],
    }
  }
}

So what I want to do is search through the students key of subjects for all students who do history and then create another array from that, taking the whole student, while leaving the original object the same.

So I want to end up with something that like this:

{
  "historyStudents": {
    "AB10001": {
      "campus": "cda",
      "subjects": ["history", "english"],
    }
    "AB10004": {
      "campus": "asd",
      "subjects": ["history"],
    }
    "AB10008": {
      "campus": "asd",
      "subjects": ["science", "history"],
    }
    "AB10009": {
      "campus": "cda",
      "subjects": ["history"],
    }
    "AB10010": {
      "campus": "cda",
      "subjects": ["history", "maths"],
    }
  }
}

Any insights or assistance would be very helpful. Thanks in advance!

2

4 Answers 4

2

You can use Object.keys() and reduce() to create new object with only students with history subject.

var data = {"students":{"AB10001":{"campus":"cda","subjects":["history","english"]},"AB10002":{"campus":"asd","subjects":["maths"]},"AB10003":{"campus":"asd","subjects":["english"]},"AB10004":{"campus":"asd","subjects":["history"]},"AB10005":{"campus":"cda","subjects":["maths","science"]},"AB10006":{"campus":"asd","subjects":["science"]},"AB10007":{"campus":"cda","subjects":["science"]},"AB10008":{"campus":"asd","subjects":["science","history"]},"AB10009":{"campus":"cda","subjects":["history"]},"AB10010":{"campus":"cda","subjects":["history","maths"]}}}

var result = {
 historyStudents: Object.keys(data.students)
  .reduce(function(r, e) {
    if(data.students[e].subjects.includes('history')) r[e] = data.students[e]
    return r;
   }, {})
 }

console.log(result)

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Nenad, this was similar to the route I was trying although this method produced the same result as I was getting. The issue with them results was that the student ID was not being sent into the new object. If you compare the result you are getting to the desired result I wanted, its similar, but not the same.
@NenadVracar Yes now it returns the exact result, the right thing was to loop over the keys .
1

You need just to loop over the data.students keys using Object.keys() and for each one check if the relative object value has history in its subjetcs array:

var result = {
  "historyStudents": {}
};

Object.keys(data.students).forEach(function(k) {
  if (data.students[k].subjects.indexOf("history") > -1) {
    result.historyStudents[k] = data.students[k];
  }
});

Demo:

var data = {
  "students": {
    "AB10001": {
      "campus": "cda",
      "subjects": ["history", "english"],
    },
    "AB10002": {
      "campus": "asd",
      "subjects": ["maths"],
    },
    "AB10003": {
      "campus": "asd",
      "subjects": ["english"],
    },
    "AB10004": {
      "campus": "asd",
      "subjects": ["history"],
    },
    "AB10005": {
      "campus": "cda",
      "subjects": ["maths", "science"],
    },
    "AB10006": {
      "campus": "asd",
      "subjects": ["science"],
    },
    "AB10007": {
      "campus": "cda",
      "subjects": ["science"],
    },
    "AB10008": {
      "campus": "asd",
      "subjects": ["science", "history"],
    },
    "AB10009": {
      "campus": "cda",
      "subjects": ["history"],
    },
    "AB10010": {
      "campus": "cda",
      "subjects": ["history", "maths"],
    }
  }
};
var result = {
  "historyStudents": {}
};

Object.keys(data.students).forEach(function(k) {
  if (data.students[k].subjects.indexOf("history") > -1) {
    result.historyStudents[k] = data.students[k];
  }
});
console.log(result);

Comments

0

In addition to above answers you can also es6 destructuring to get the desired result

const  data = {"students":{"AB10001":{"campus":"cda","subjects":["history","english"]},"AB10002":{"campus":"asd","subjects":["maths"]},"AB10003":{"campus":"asd","subjects":["english"]},"AB10004":{"campus":"asd","subjects":["history"]},"AB10005":{"campus":"cda","subjects":["maths","science"]},"AB10006":{"campus":"asd","subjects":["science"]},"AB10007":{"campus":"cda","subjects":["science"]},"AB10008":{"campus":"asd","subjects":["science","history"]},"AB10009":{"campus":"cda","subjects":["history"]},"AB10010":{"campus":"cda","subjects":["history","maths"]}}}

const historyStudents = {};
for(const stdId in data.students) {

  // es6 destructuring
  const { subjects } = data.students[stdId];

  if(subjects.includes('history')){
    historyStudents[stdId] = data.students[stdId]; 
  }
}
// object property shorthand
console.log({ historyStudents });

Comments

0

You could get the keys, filter it and build a new object out of the key and the values. Then use Object.assign for creating a single object.

function getStudents(object, subject) {
    return Object.assign({}, ...Object
        .keys(object)
        .filter(k => object[k].subjects.includes(subject))
         .map(k => ({ [k]: object[k] }))
    );
}


var object = { students: { AB10001: { campus: "cda", subjects: ["history", "english"] }, AB10002: { campus: "asd", subjects: ["maths"] }, AB10003: { campus: "asd", subjects: ["english"] }, AB10004: { campus: "asd", subjects: ["history"] }, AB10005: { campus: "cda", subjects: ["maths", "science"] }, AB10006: { campus: "asd", subjects: ["science"] }, AB10007: { campus: "cda", subjects: ["science"] }, AB10008: { campus: "asd", subjects: ["science", "history"] }, AB10009: { campus: "cda", subjects: ["history"] }, AB10010: { campus: "cda", subjects: ["history", "maths"] } } },
    result = { historyStudents: getStudents(object.students, 'history') };

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

Your Answer

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.