Count in JavaScript - javascript

If I have an object like this in javascript, how can I count the number of elements in [A, B, C, D, etc.]?
{ "test" : [ "A", "B", "C", "D", ... ] }
And if i have:
{ "_id" : "1", "value" : { "test" : [ "A", "B", "C", "D" ] } }
{ "_id" : "2", "value" : { "test" : [ "A", "B", "C", "D", "E", "F" ] } }
How can I convert it to the following structure?
{ "_id" : "1", "value" : 4 }
{ "_id" : "2", "value" : 6 }
Thanks

Try the following:
var data = [{ "_id" : "1", "value" : { "test" : [ "A", "B", "C", "D" ] } },{ "_id" : "2", "value" : { "test" : [ "A", "B", "C", "D", "E","F" ] } }];
var arr = data.map((d) => {
d["value"] = d["value"].test.length;
return d;
});
console.log(arr);
EDIT
The more smart way is to simply use a forEach loop in the following way
var data = [{ "_id" : "1", "value" : { "test" : [ "A", "B", "C", "D" ] } },{ "_id" : "2", "value" : { "test" : [ "A", "B", "C", "D", "E","F" ] } }];
data.forEach((d) => {
d["value"] = d["value"].test.length;
});
console.log(data);

If can always do .length on an object check the example below:
var obj = { "test" : [ "A", "B", "C", "D", "E", "F"] };
console.log(obj.test.length)
EDIT:
For your second question
you can do
obj.value = obj.value.test.length;
var obj = { "_id" : "2", "value" : { "test" : [ "A", "B", "C", "D", "E", "F" ] } };
obj.value = obj.value.test.length;
console.log(obj)

As the answer changed from generic javascript to mongodb, I have to update the answer to reflect the question:
Instead of using map/reduce in mongo, consider using the aggregation framework mongodb provides, it allows for very powerful querying.
In this case, you want the $size operator
db.yourCollection.aggregate([
{ $project: { value: { $size: "$value.test" } } }
])
Unless explicitly removed, mongodb will always include the document _id so for this use case we only need to address the value, if you need any other value from the documents in your result-set, add them like:
db.yourCollection.aggregate([
{ $project: {
value: { $size: "$value.test" },
foo: '$foo',
bar: '$bar',
baz: '$baz',
} }
])
Original answer (pure js, no mongodb)
I suspect the example is actually part of an array
{ "_id" : "1", "value" : { "test" : [ "A", "B", "C", "D" ] } }
{ "_id" : "2", "value" : { "test" : [ "A", "B", "C", "D", "E" ] } }
So I assume you want to map a large set of records this way, and you don't want to (accidentally) destroy the original value property (as other answers do), here's how I'd do this:
const list = [
{ "_id" : "1", "value" : { "test" : [ "A", "B", "C", "D" ] } },
{ "_id" : "2", "value" : { "test" : [ "A", "B", "C", "D", "E" ] } }
];
// map the list into a new list of object containing the _id and value count
const mapped = list.map((record) => {
return {
_id: record._id,
// assuming there's only test and it's an array
value: record.value.test.length,
};
});
If value inside each record is an object which may contain zero or more arrays and you wish to count the total amount of items inside all of them, you can reduce the arrays into a total number.
const list = [
{ "_id" : "1", "value" : { "test" : [ "A", "B", "C", "D" ] } },
{ "_id" : "2", "value" : { "test" : [ "A", "B", "C", "D", "E" ] } },
{ "_id" : "3", "value" : { } },
{ "_id" : "4", "value" : { "test" : [ "A", "B" ], "test2" : [ "C", "D", "E" ] } },
];
// map the list into a new list of object containing the _id and value count
const mapped = list.map((record) => {
return {
_id: record._id,
// assuming there's zero or more arrays
value: Object.keys(record.value)
// filter out any non-array
.filter((key) => Array.isArray(record.value[key]))
// reduce the arrays into their combined length
.reduce((carry, key) => carry + record.value[key].length, 0),
};
});
console.log(mapped);

You can transform your array with a simple forEach loop - like below:
var data = [{
"_id": "1",
"value": {
"test": ["A", "B", "C", "D"]
}
},
{
"_id": "2",
"value": {
"test": ["A", "B", "C", "D", "E"]
}
}
];
var dataCount = [];
data.forEach(function(element) {
var newElement = {};
newElement._id = element._id;
newElement.value = element.value.test.length;
dataCount.push(newElement);
//console.log(newElement);
});
console.log(dataCount);

Related

I want to compare inner array in JSON array of object and return new array depending on condition using JavaScript

I have following array of object
let studentArray =
[{
"name" : "Computer Science",
"students" : [
{
"student_name" : "A"
},
{
"student_name" : "B"
}
]
},
{
"name" : "Math",
"students" : [
{
"student_name" : "A"
},
{
"student_name" : "B"
},
{
"student_name" : "C"
}
]
}]
and I want answer like below.
[
{
"student_name" : "A",
"courses": ["Computer Science", "Math"]
},
{
"student_name" : "B",
"courses": ["Computer Science", "Math"]
},
{
"student_name" : "C",
"courses": ["Math"]
}
]
Please help with javascript functionality and according to data structure algorithm.
I have tried below it is not working.
I there any another way to doing this Using different another loops or something another logic for that.
let studentArray = [{
"name": "Computer Science",
"students": [{
"student_name": "A"
},
{
"student_name": "B"
}
]
},
{
"name": "Math",
"students": [{
"student_name": "A"
},
{
"student_name": "B"
},
{
"student_name": "C"
}
]
}
]
studentArray.forEach((item, index) => {
//console.log(item);
if (index > 0) {
console.log("Previous: " + studentArray[index - 1].students);
}
if (index < studentArray.length - 1) {
console.log("Next: " + studentArray[index + 1].students);
}
//console.log(studentArray);
console.log(item.students.filter(comparer(item.students)));
});
function comparer(otherArray) {
return function(current) {
return otherArray.filter(function(other) {
return other.value == current.value && other.display == current.display
}).length == 0;
}
}
You can use Array.reduce() on the studentArray to group students with their courses.
We create an object keyed by student name and iterate over each course's student array to add students to the map (using for...each).
Finally, we use Object.values() to turn our map into an array:
const studentArray = [{ "name" : "Computer Science", "students" : [ { "student_name" : "A" }, { "student_name" : "B" } ] }, { "name" : "Math", "students" : [ { "student_name" : "A" }, { "student_name" : "B" }, { "student_name" : "C" } ] }];
const result = Object.values(studentArray.reduce((acc, course) => {
for(let student of course.students) {
let student_name = student.student_name;
acc[student_name ] = acc[student_name ] || { student_name , courses: []};
acc[student_name ].courses.push(course.name);
}
return acc;
}, {}))
console.log(result)
Use a nested forEach loop
const studentArray = [{
name: "Computer Science",
students: [{
student_name: "A"
},
{
student_name: "B"
}
]
},
{
name: "Math",
students: [{
student_name: "A"
},
{
student_name: "B"
},
{
student_name: "C"
}
]
}
];
const newArr = [];
studentArray.forEach((c) => {
c.students.forEach((s) => {
let studentIndex = newArr.findIndex(el => el.student_name === s.student_name);
studentIndex === -1 ? newArr.push({
student_name: s.student_name,
courses: [c.name]
}) : newArr[studentIndex].courses.push(c.name)
})
})
console.log(newArr);
Another approach using reduce, map, and some ES6 spread syntax:
const courses = [
{
"name" : "Computer Science",
"students" : [{ "student_name" : "A" }, { "student_name" : "B" }]
},
{
"name" : "Math",
"students" : [{ "student_name" : "A" }, { "student_name" : "B" }, { "student_name" : "C" }]
}
]
// Add students from a course to an array if they're not present already
const selectUniqueStudents = (currentStudentList, course) =>
currentStudentList.concat(course.students.filter(newStudent =>
currentStudentList.every(
currentStudent => currentStudent.student_name !== newStudent.student_name
)
))
// Add each course that the student is on to an array and append to the
// student object
const addCourseDetails = (student) => ({
...student,
courses: courses
.filter(course =>
course.students.some(courseStudent => courseStudent.student_name === student.student_name)
)
.map(course => course.name)
})
const transformedResult = courses
.reduce(selectUniqueStudents, [])
.map(addCourseDetails)
console.log(transformedResult)
// Returns:
//
// [
// { student_name: 'A', courses: [ 'Computer Science', 'Math' ] },
// { student_name: 'B', courses: [ 'Computer Science', 'Math' ] },
// { student_name: 'C', courses: [ 'Math' ] }
// ]
Same as with Vineet's answer, Terry's would run faster. This is not as concise or easy to read either. But the demonstration of aggregate array functions and ES6 syntax might be useful.

Remove array from array if there is certain value in Object

I want to remove array which is inside of whole array if an object of its array has certain value. I searched the web and I saw removing object or array if it has certain value and I can't find that solves my problem.
I have objects of array which is again wrapped by array. It looks like below:
"products": [
[
{
"product.name": "A",
"remark.name": "Good"
},
{
"product.name": "B",
"remark.name": "Good"
}
],
[
{
"product.name": "A",
"remark.name": "Bad"
},
{
"product.name": "B",
"remark.name": "Good"
}
]
]
What I want
I want to omit the whole array which contains at least remark.name === Bad
So, I should get the final result like below.
"products": [
[
{
"product.name": "A",
"remark.name": "Good"
},
{
"product.name": "B",
"remark.name": "Good"
}
]
]
What I've tried
Below code
let result = [];
products.map((product) => {
var res = _.remove(product, function (n) {
return n["remark.name"] === "Fail";
});
result.push(res);
});
produces following result:
"products": [
[
{
"product.name": "A",
"remark.name": "Good"
},
{
"product.name": "B",
"remark.name": "Good"
}
],
[
{
"product.name": "B",
"remark.name": "Good"
}
]
]
Use Array#filter for filtering and as filter Array#every where remark.name is different from 'Bad'.
Note: Use single or double quotes for propertyname 'remark.name' because of the dot in it`s name.
let products = [
[
{
"product.name": "A",
"remark.name": "Good"
},
{
"product.name": "B",
"remark.name": "Good"
}
],
[
{
"product.name": "A",
"remark.name": "Bad"
},
{
"product.name": "B",
"remark.name": "Good"
}
]
];
let filtered = products.filter(arr => arr.every(obj => obj['remark.name'] !== 'Bad'));
console.log(filtered);

How to prepare JSON for export to CSV

I want to parse json loaded from file const notCleanData = JSON.parse(fs.readFileSync('db.json')); to be able to export to CSV using json2csv. I loaded the file and learn how to export, but I can't figure out how to clean JSON from unnecessary part of JSON, cos it's making CSV to be exported in a wrong way. Instead having data from array in separate columns, I get all data under one column with "group" as header. How to convert A.json to B.json for exporting clean JSON to CSV?
A.json
{
"group" : [
{
"A" : "1",
"B" : "2"
},
{
"A" : "3",
"B" : "4"
}
],
"profile" : {
"C" : "5"
}
}
B.json
{
"A" : "1",
"B" : "2"
},
{
"A" : "3",
"B" : "4"
}
In short: How to extract data only from "group" and add it to variable?
You can use jpath for that:
let A = {
"group" : [
{
"A" : "1",
"B" : "2"
},
{
"A" : "3",
"B" : "4"
}
],
"profile" : {
"C" : "5"
}
}
let jp = require('jsonpath');
let B = jp.query(A, '$.group');
console.log(B)
Output:
[ [ { A: '1', B: '2' }, { A: '3', B: '4' } ] ]

Unwind Multiple Document Arrays Into New Documents

Today I run into a situation I need to sync a mongoDB collection to vertica (SQL Database) where my object keys will be the columns of the table in SQL.
I use mongoDB aggregation framework, first to query, manipulate and project the wanted result document and then I sync it to vertica.
The schema I want to aggregate looks like this:
{
userId: 123
firstProperty: {
firstArray: ['x','y','z'],
anotherAttr: 'abc'
},
anotherProperty: {
secondArray: ['a','b','c'],
anotherAttr: 'def'
}
}
Since array values are not related with other arrays value, what I need is that each value of nested array, will be in a separate result document.
For that I use the following aggregation pipe:
db.collection('myCollection').aggregate([
{
$match: {
$or: [
{'firstProperty.firstArray.1': {$exists: true}},
{'secondProperty.secondArray.1': {$exists: true}}
]
}
},
{
$project: {
userId: 1,
firstProperty: 1,
secondProperty: 1
}
}, {
$unwind: {path:'$firstProperty.firstAray'}
}, {
$unwind: {path:'$secondProperty.secondArray'},
}, {
$project: {
userId: 1,
firstProperty: '$firstProperty.firstArray',
firstPropertyAttr: '$firstProperty.anotherAttr',
secondProperty: '$secondProperty.secondArray',
seondPropertyAttr: '$secondProperty.anotherAttr'
}
}, {
$out: 'another_collection'
}
])
What I expect is the following result:
{
userId: 'x1',
firstProperty: 'x',
firstPropertyAttr: 'a'
}
{
userId: 'x1',
firstProperty: 'y',
firstPropertyAttr: 'a'
}
{
userId: 'x1',
firstProperty: 'z',
firstPropertyAttr: 'a'
}
{
userId: 'x1',
secondProperty: 'a',
firstPropertyAttr: 'b'
}
{
userId: 'x1',
secondProperty: 'b',
firstPropertyAttr: 'b'
}
{
userId: 'x1',
secondProperty: 'c',
firstPropertyAttr: 'b'
}
Instead I get something like that:
{
userId: 'x1',
firstProperty: 'x',
firstPropertyAttr: 'b'
secondProperty: 'a',
secondPropertyAttr: 'b'
}
{
userId: 'x1',
firstProperty: 'y',
firstPropertyAttr: 'b'
secondProperty: 'b',
secondPropertyAttr: 'b'
}
{
userId: 'x1',
firstProperty: 'z',
firstPropertyAttr: 'b'
secondProperty: 'c',
secondPropertyAttr: 'b'
}
What exactly am I missing, and how can I fix it?
This is actually a much "curlier" problem than you might think it is, and it all really boils down to "named keys", which are generally a real problem and your data "should" not be using "data points" in the naming of such keys.
The other obvious problem in your attempt is called a "cartesian product". This is where you $unwind one array and then $unwind another, which results in the items from the "first" $unwind being repeated for every value present in the "second".
Addressing that second problem, the basic approach is to "combine the arrays" in order that you only $unwind from a single source. This is pretty common to all remaining approaches.
As for the approaches, these differ in the MongoDB version you have available and the general practicality of application. So let's step through them:
Remove the named keys
The most simple approach here is to simply not expect named keys in the output, and instead mark them as a "name" identifying their source in the final output. So all we want to do is specify each "expected" key within the construction of an initial "combined" array, and then simply $filter that for any null values resulting from named paths not existing in the present document.
db.getCollection('myCollection').aggregate([
{ "$match": {
"$or": [
{ "firstProperty.firstArray.0": { "$exists": true } },
{ "anotherProperty.secondArray.0": { "$exists": true } }
]
}},
{ "$project": {
"_id": 0,
"userId": 1,
"combined": {
"$filter": {
"input": [
{
"name": { "$literal": "first" },
"array": "$firstProperty.firstArray",
"attr": "$firstProperty.anotherAttr"
},
{
"name": { "$literal": "another" },
"array": "$anotherProperty.secondArray",
"attr": "$anotherProperty.anotherAttr"
}
],
"cond": {
"$ne": ["$$this.array", null ]
}
}
}
}},
{ "$unwind": "$combined" },
{ "$unwind": "$combined.array" },
{ "$project": {
"userId": 1,
"name": "$combined.name",
"value": "$combined.array",
"attr": "$combined.attr"
}}
])
From the data included in your question this would produce:
/* 1 */
{
"userId" : 123.0,
"name" : "first",
"value" : "x",
"attr" : "abc"
}
/* 2 */
{
"userId" : 123.0,
"name" : "first",
"value" : "y",
"attr" : "abc"
}
/* 3 */
{
"userId" : 123.0,
"name" : "first",
"value" : "z",
"attr" : "abc"
}
/* 4 */
{
"userId" : 123.0,
"name" : "another",
"value" : "a",
"attr" : "def"
}
/* 5 */
{
"userId" : 123.0,
"name" : "another",
"value" : "b",
"attr" : "def"
}
/* 6 */
{
"userId" : 123.0,
"name" : "another",
"value" : "c",
"attr" : "def"
}
Merge Objects - Requires MongoDB 3.4.4 minimum
To actually use "named keys" we need the $objectToArray and $arrayToObject operators that were only available since MongoDB 3.4.4. Using these and the $replaceRoot pipeline stage we can simply process to your desired output without explicitly naming the keys to output at any stage:
db.getCollection('myCollection').aggregate([
{ "$match": {
"$or": [
{ "firstProperty.firstArray.0": { "$exists": true } },
{ "anotherProperty.secondArray.0": { "$exists": true } }
]
}},
{ "$project": {
"_id": 0,
"userId": 1,
"data": {
"$reduce": {
"input": {
"$map": {
"input": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"cond": { "$not": { "$in": [ "$$this.k", ["_id", "userId"] ] } }
}
},
"as": "d",
"in": {
"$let": {
"vars": {
"inner": {
"$map": {
"input": { "$objectToArray": "$$d.v" },
"as": "i",
"in": {
"k": {
"$cond": {
"if": { "$ne": [{ "$indexOfCP": ["$$i.k", "Array"] }, -1] },
"then": "$$d.k",
"else": { "$concat": ["$$d.k", "Attr"] }
}
},
"v": "$$i.v"
}
}
}
},
"in": {
"$map": {
"input": {
"$arrayElemAt": [
"$$inner.v",
{ "$indexOfArray": ["$$inner.k", "$$d.k"] }
]
},
"as": "v",
"in": {
"$arrayToObject": [[
{ "k": "$$d.k", "v": "$$v" },
{
"k": { "$concat": ["$$d.k", "Attr"] },
"v": {
"$arrayElemAt": [
"$$inner.v",
{ "$indexOfArray": ["$$inner.k", { "$concat": ["$$d.k", "Attr"] }] }
]
}
}
]]
}
}
}
}
}
}
},
"initialValue": [],
"in": { "$concatArrays": [ "$$value", "$$this" ] }
}
}
}},
{ "$unwind": "$data" },
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$concatArrays": [
[{ "k": "userId", "v": "$userId" }],
{ "$objectToArray": "$data" }
]
}
}
}}
])
Which gets pretty monstrous from converting the "keys" into an array, then the "sub-keys" into an array and mapping the values from those inner arrays onto the pair of keys in output.
The key parts being $objectToArray is essentially needed to "transform" your "nested key" structures into arrays of "k" and "v" representing the "name" of the key and the "value". This gets called twice, being once for the "outer" parts of the document and excluding the "constant" fields such as "_id" and "userId" into such an array structure. Then the second call is processed on each of those "array" elements in order to make those "inner keys" a similar "array".
Matching is then done using $indexOfCP to work out which "inner key" is the one for the value and which is the "Attr". The keys are then renamed here to the "outer" key value, which we can access because that's a "v" courtesy of $objectToArray.
Then for the "inner value" which is an "array", we want to $map each entry into a combined "array" which basically has the form:
[
{ "k": "firstProperty", "v": "x" },
{ "k": "firstPropertyAttr", "v": "abc" }
]
This happens for each "inner array" element, for which $arrayToObject reverses the process and turns each "k" and "v" into "key" and "value" of an object respectively.
Since the output is still an "array of arrays" of the "inner keys" at this point, the $reduce wraps that output and applies $concatArrays while processing each element in order to "join" into a single array for "data".
All that remains is to simply $unwind the array produced from each source document, and then apply $replaceRoot, which is the part that actually allows "different key names" at the "root" of each document output.
The "merging" here is done by supplying an array of object of the same "k" and "v" construction notated for "userId", and "concatentating" that with the $objectToArray transform of the "data". Of course this "new array" is then converted to an object via $arrayToObject one final time, which forms the "object" argument to "newRoot" as an expression.
You do something like that when there is a large number of "named keys" that you can't really name explicitly. And it actually gives you the result you want:
/* 1 */
{
"userId" : 123.0,
"firstProperty" : "x",
"firstPropertyAttr" : "abc"
}
/* 2 */
{
"userId" : 123.0,
"firstProperty" : "y",
"firstPropertyAttr" : "abc"
}
/* 3 */
{
"userId" : 123.0,
"firstProperty" : "z",
"firstPropertyAttr" : "abc"
}
/* 4 */
{
"userId" : 123.0,
"anotherProperty" : "a",
"anotherPropertyAttr" : "def"
}
/* 5 */
{
"userId" : 123.0,
"anotherProperty" : "b",
"anotherPropertyAttr" : "def"
}
/* 6 */
{
"userId" : 123.0,
"anotherProperty" : "c",
"anotherPropertyAttr" : "def"
}
Named Keys without MongoDB 3.4.4 or Greater
Without the operator support as shown in the above listing, it's simply not possible for the aggregation framework to output documents with different key names.
So though it's not possible to instruct the "server" to do this via $out, you can of course simply iterate the cursor and write a new collection
var ops = [];
db.getCollection('myCollection').find().forEach( d => {
ops = ops.concat(Object.keys(d).filter(k => ['_id','userId'].indexOf(k) === -1 )
.map(k =>
d[k][Object.keys(d[k]).find(ki => /Array$/.test(ki))]
.map(v => ({
[k]: v,
[`${k}Attr`]: d[k][Object.keys(d[k]).find(ki => /Attr$/.test(ki))]
}))
)
.reduce((acc,curr) => acc.concat(curr),[])
.map( o => Object.assign({ userId: d.userId },o) )
);
if (ops.length >= 1000) {
db.getCollection("another_collection").insertMany(ops);
ops = [];
}
})
if ( ops.length > 0 ) {
db.getCollection("another_collection").insertMany(ops);
ops = [];
}
Same sort of thing as is being done in the earlier aggregation, but just "externally". It essentially produces and array of documents for each document matching the "inner" arrays, like so:
[
{
"userId" : 123.0,
"firstProperty" : "x",
"firstPropertyAttr" : "abc"
},
{
"userId" : 123.0,
"firstProperty" : "y",
"firstPropertyAttr" : "abc"
},
{
"userId" : 123.0,
"firstProperty" : "z",
"firstPropertyAttr" : "abc"
},
{
"userId" : 123.0,
"anotherProperty" : "a",
"anotherPropertyAttr" : "def"
},
{
"userId" : 123.0,
"anotherProperty" : "b",
"anotherPropertyAttr" : "def"
},
{
"userId" : 123.0,
"anotherProperty" : "c",
"anotherPropertyAttr" : "def"
}
]
These get "cached" into a big array, which when that reaches a length of 1000 or more is finally written to the new collection via .insertMany(). Of course that requires "back and forth" communication with the server, but it does get the job done in the most efficient way possible if you don't have the features available for the previous aggregation.
Conclusion
The overall point here is that unless you actually have a MongoDB that supports it, then you are not going to get documents with "different key names" in the output, solely from the aggregation pipeline.
So when you do not have that support, you either go with the first option and then use $out discarding having named keys. Or you do the final approach and simply manipulate the cursor results and write back to the new collection.

Iterating json array objects using node js

I have got a task to iterate through the complex json file that contains json array. I could not access the array object from the json file.
I need to access the particularly the class-name object from the json
file.
classdetail.json
[ [ { "student" : [
{
"name" : "AAaa",
"class-name" : "A",
"grade-label" : "AA" },
{
"name" : "AAbb",
"class-name" : "A",
"grade-label" : "AB" },
{
"name" : "AAcc",
"class-name" : "A",
"grade-label" : "AB" },
{
"name" : "AAdd",
"class-name" : "B",
"grade-label" : "AA" } ],
"Average" : 2.5 },
{
"student" : [
{
"name" : "BBaa",
"class-name" : "B",
"grade-label" : "AB" },
{
"name" : "BBbb",
"class-name" : "B",
"grade-label" : "AA" },
{
"name" : "BBcc",
"class-name" : "B",
"grade-label" : "AA" },
{
"name" : "BBdd",
"class-name" : "B",
"grade-label" : "AA" } ],
"Average" : 2.5 } ] ]
iterate.js
var fs = require('fs');
var express = require('express');
var http = require('http');
var publicApis;
var item;
var subItem;
classmem = JSON.parse(fs.readFileSync("classdetail.json", "utf8"));
for (item in classmem) {
for (subItem in classmem[item]) {
console.log(classmem[item][subItem]);
}
}
for (item in classmem) {
for (subItem in classmem[item]) {
var student = classmem[item][subItem].student;
for (row in student) {
console.log(student[row]['class-name']);
}
}
}
But read about Array.forEach.
for...in iterates over object properties in arbitrary order. It might not be what you want to use for an array, which stores items in a well-defined order. (though it should work in this case)
Try Array.forEach():
// iterate over `classmem`
classmem.forEach(function(element, index, array) {
// iterate over classmem[index], which is an array too
element.forEach(function(el, idx, arr) {
// classmem[index][idx] contains objects with a `.student` property
el.student.forEach(function(e, i, a) {
console.log(e["name"], e["class-name"], e["grade-label"]);
});
});
});
first check the value is array then access to the "class-name" value
for (item in classmem) {
for (subItem in classmem[item]) {
**if (typeof classmem[item][subItem] === 'object') {
classmem[item][subItem].forEach(function (val, ind) {
console.log(val['class-name']);
});
}**
}
}

Categories

Resources