I am working on an LMS project where the end-user will click on a check box indicating a particular lesson is marked as complete. based on the number of lessons marked as completed, I need to showcase the percentage of course completion.
If there are 6 lessons and the user marked 3 lessons as completed, the math is 3/6 *100 = 50%.
Below is how my input JSON document looks like
[
{
"__typename": "ps_lessons",
"lesson_id": 1,
"id": "c9243c5b-2bf4-4afd-ab75-5fb7587b0d4f",
"lesson_title": "Lesson 1",
"multi_learners": [
{
"__typename": "ps_lesson_learners",
"id": "5567c2a2-e0ff-4015-9bc6-a472b7683b01",
"lesson_id": "c9243c5b-2bf4-4afd-ab75-5fb7587b0d4f",
"check": true
}
],
},
{
"__typename": "ps_lessons",
"lesson_id": 2,
"id": "e3a26cc4-793e-4e56-bd30-c14a15633e5f",
"lesson_title": "Lesson 2",
"multi_learners": [
{
"__typename": "ps_lesson_learners",
"id": "246e47e6-1821-4aae-9e2a-7abfd848ad4b",
"lesson_id": "e3a26cc4-793e-4e56-bd30-c14a15633e5f",
"check": true
}
],
},
{
"__typename": "ps_lessons",
"lesson_id": 3,
"id": "981e53c6-a63c-4a6f-84df-286c356b6a41",
"multi_learners": [
{
"__typename": "ps_lesson_learners",
"id": "52f44453-eb6a-4694-ba38-cfb6f96ab50d",
"lesson_id": "981e53c6-a63c-4a6f-84df-286c356b6a41",
"check": false
}
],
},
{
"__typename": "ps_lessons",
"lesson_id": 4,
"id": "88a7c331-0029-451e-b408-d35fbfd8f3f9",
},
{
"__typename": "ps_lessons",
"lesson_id": 5,
"id": "88a7c331-0029-451e-84df-286c356b6a41",
}
]
in the above document there are a total of 5 ps_lessons
elements are there for every element there is a sub-element ps_lesson_learners
where multi_learners[0].check
indicates the user's selection.
So I need to figure it out, if there is a subelement i.e. ps_lesson_learners
if the subelement is present then check the true
value for multi_learners[0].check
and divide it with the total lessons and multiply by 100 to get the percentage.
there are a total of 2 true status out of 5 lessons so it will be 2/5 * 100 = 40%
I tried some thing like below with map
method and coudln't able to get the result
data.map((data)=>{
if (data.multi_learners.length == 1) {
if (data.multi_learners[0].check == 'true') {
count = count 1;
}
}
});
final_count = count * data.length/100
Appreciate your help with the code.
Thanks Venk
CodePudding user response:
You could use Array.filter()
to count the number of completed lessons:
let input = [ { "__typename": "ps_lessons", "lesson_id": 1, "id": "c9243c5b-2bf4-4afd-ab75-5fb7587b0d4f", "lesson_title": "Lesson 1", "multi_learners": [ { "__typename": "ps_lesson_learners", "id": "5567c2a2-e0ff-4015-9bc6-a472b7683b01", "lesson_id": "c9243c5b-2bf4-4afd-ab75-5fb7587b0d4f", "check": true } ], }, { "__typename": "ps_lessons", "lesson_id": 2, "id": "e3a26cc4-793e-4e56-bd30-c14a15633e5f", "lesson_title": "Lesson 2", "multi_learners": [ { "__typename": "ps_lesson_learners", "id": "246e47e6-1821-4aae-9e2a-7abfd848ad4b", "lesson_id": "e3a26cc4-793e-4e56-bd30-c14a15633e5f", "check": true } ], }, { "__typename": "ps_lessons", "lesson_id": 3, "id": "981e53c6-a63c-4a6f-84df-286c356b6a41", "multi_learners": [ { "__typename": "ps_lesson_learners", "id": "52f44453-eb6a-4694-ba38-cfb6f96ab50d", "lesson_id": "981e53c6-a63c-4a6f-84df-286c356b6a41", "check": false } ], }, { "__typename": "ps_lessons", "lesson_id": 4, "id": "88a7c331-0029-451e-b408-d35fbfd8f3f9", }, { "__typename": "ps_lessons", "lesson_id": 5, "id": "88a7c331-0029-451e-84df-286c356b6a41", } ]
function getCompletedCount(input) {
return input.filter(input => input.multi_learners &&
input.multi_learners[0] &&
input.multi_learners[0].check).length;
}
console.log('Completed count:', getCompletedCount(input))
console.log('Completed %:', 100*getCompletedCount(input)/input.length)
.as-console-wrapper { max-height: 100% !important; }
You can also use Optional chaining
if your environment allows it (e.g. Chrome version >= 80, Node version >= 14.0)
let input = [ { "__typename": "ps_lessons", "lesson_id": 1, "id": "c9243c5b-2bf4-4afd-ab75-5fb7587b0d4f", "lesson_title": "Lesson 1", "multi_learners": [ { "__typename": "ps_lesson_learners", "id": "5567c2a2-e0ff-4015-9bc6-a472b7683b01", "lesson_id": "c9243c5b-2bf4-4afd-ab75-5fb7587b0d4f", "check": true } ], }, { "__typename": "ps_lessons", "lesson_id": 2, "id": "e3a26cc4-793e-4e56-bd30-c14a15633e5f", "lesson_title": "Lesson 2", "multi_learners": [ { "__typename": "ps_lesson_learners", "id": "246e47e6-1821-4aae-9e2a-7abfd848ad4b", "lesson_id": "e3a26cc4-793e-4e56-bd30-c14a15633e5f", "check": true } ], }, { "__typename": "ps_lessons", "lesson_id": 3, "id": "981e53c6-a63c-4a6f-84df-286c356b6a41", "multi_learners": [ { "__typename": "ps_lesson_learners", "id": "52f44453-eb6a-4694-ba38-cfb6f96ab50d", "lesson_id": "981e53c6-a63c-4a6f-84df-286c356b6a41", "check": false } ], }, { "__typename": "ps_lessons", "lesson_id": 4, "id": "88a7c331-0029-451e-b408-d35fbfd8f3f9", }, { "__typename": "ps_lessons", "lesson_id": 5, "id": "88a7c331-0029-451e-84df-286c356b6a41", } ]
function getCompletedCount(input) {
return input.filter(input => input?.multi_learners?.[0]?.check).length;
}
console.log('Completed count:', getCompletedCount(input))
console.log('Completed %:', 100*getCompletedCount(input)/input.length)
.as-console-wrapper { max-height: 100% !important; }
CodePudding user response:
.map()
is not what you are looking for as it returns an array with each element in the output corresponding to each of the input. You can use .reduce()
instead:
data.reduce((count, each) => count each.multi_learners?.length == 1 && each.multi_learners[0].check == 'true' ? 1 : 0, 0)
or instead of using a ternary, cast the boolean as Number:
data.reduce((count, each) => count Number(each.multi_learners?.length == 1 && each.multi_learners[0].check == 'true'), 0)
This doesn't incur two loops of first filtering then counting the length of those that survived the filter.