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!

Dev365
  • 57
  • 3

4 Answers4

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)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
  • 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. – Dev365 Oct 17 '17 at 15:59
  • @NenadVracar Yes now it returns the exact result, the right thing was to loop over the `keys` . – cнŝdk Oct 17 '17 at 16:09
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);
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
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; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
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 });
vs1682
  • 545
  • 2
  • 12