You have practiced with a study planner. Now transfer those skills to a reading log. Begin with a blank function, not the planner’s implementation. You may consult earlier explanations and use the hints; record what help you needed so you know what to revisit.
Your brief
Write readingReport(entries). Each entry has a title string and a pages number. Return a string in the form Books: 2; pages: 35. Only accept entries with a nonblank title and a positive whole-number page count. Ignore invalid entries. An empty array must return Books: 0; pages: 0. Do not change the input records.
For this exercise the input is always an array of objects with title and pages properties; title may be a non-string and pages may be any value. Validate both before using string methods or adding pages. Duplicate titles count as separate entries. Write checks for ordinary data, an empty array, blank titles, a non-string title, zero, and fractional pages.
Work in stages: describe valid input in a sentence; inspect one record; implement the validation; accumulate the results; format the report. You do not need a webpage or a new library.
Predict before running
This example gives you the shape of the input, not the solution. Which of its records should count?
const entries = [
{ title: "A small book", pages: 20 },
{ title: "Another book", pages: 15 },
{ title: " ", pages: 10 }
];
console.log(entries.length);Check your prediction
3Trace each statement in order. If your prediction differed, describe the first place your mental model and the result diverged before trying again.
Your turn
On Your Own: Reading Report: practise
Implement readingReport and your own checks. The three records above must produce Books: 2; pages: 35. Try the edge cases in the brief before comparing with the solution.
function readingReport(entries) {
// Write your implementation here.
}
// Add checks from the brief.Hint 1: the idea
Use two accumulators: accepted record count and page total. Validate before adding.
Hint 2: a first step
Check typeof entry.title === “string” before calling trim. Combine it with Number.isInteger(entry.pages) and entry.pages > 0.
Show one solution
function readingReport(entries) {
let count = 0;
let pages = 0;
for (const entry of entries) {
const valid =
typeof entry.title === "string" &&
entry.title.trim() !== "" &&
Number.isInteger(entry.pages) &&
entry.pages > 0;
if (valid) {
count = count + 1;
pages = pages + entry.pages;
}
}
return `Books: ${count}; pages: ${pages}`;
}
const entries = [
{ title: "A small book", pages: 20 },
{ title: "Another book", pages: 15 },
{ title: " ", pages: 10 }
];
console.log(readingReport(entries));
if (readingReport([]) !== "Books: 0; pages: 0") {
throw new Error("empty");
}
const invalid = [
{ title: 42, pages: 10 },
{ title: "Zero", pages: 0 },
{ title: "Half", pages: 1.5 },
{ title: "Text", pages: "20" }
];
if (readingReport(invalid) !== "Books: 0; pages: 0") {
throw new Error("invalid");
}Books: 2; pages: 35The && operator short-circuits: once typeof rejects a non-string title, trim is not called. Explain the chosen data structure, the function boundary, one deliberately tested edge case, and why your input stays unchanged. Solving with a hint still counts as practice; try a fresh variation later to check independence.
Before you move on
Explain the main idea in your own words, change one input, and predict the result. If you used the solution, close it and rebuild the exercise once with different values. Use Mark as done to track your place, not to certify mastery.
Completion is saved in this browser only. It does not measure mastery.