Array methods exercise

Viewed 93

I need help for this exercise:

Array methods

Implement the uncompletedNotes function which, given an array of notes, returns only the uncompleted notes. A note is considered completed if all todo present have the done flag set to true.

This is what I've done:

function uncompletedNotes(notes) {

  let result = []

  notes.forEach(element => {
    if (element.todos.done == false) {
      result.push(element);
    }
  });

  return result;

}

const notes = [{
    id: 1,
    description: 'Workout program',
    todos: [{
        id: 1,
        name: 'Push ups - 10 x 3',
        done: false
      },
      {
        id: 2,
        name: 'Abdominals - 20 x 3',
        done: true
      },
      {
        id: 3,
        name: 'Tapis Roulant - 15min',
        done: true
      }
    ]
  },
  {
    id: 2,
    description: 'Front-end Roadmap',
    todos: [{
        id: 1,
        name: 'Learn HTML',
        done: true
      },
      {
        id: 2,
        name: 'Learn CSS',
        done: true
      },
      {
        id: 3,
        name: 'Learn JavaScript',
        done: true
      },
      {
        id: 4,
        name: 'Learn Angular',
        done: true
      }
    ]
  }
]

const notesInProgress = uncompletedNotes(notes);
console.log('All notes: ', notes);
console.log('Notes In Progress: ', notesInProgress);

But it gives me an empty array result in Notes in Progress.

7 Answers
function uncompletedNotes(notes) {
    return notes.filter(note => note.todos.filter(todo => !todo.done))
}

The problem here is that the todos property of each notes is itself an array, ie there is no done property on todos. It may be useful to look at the array methods every or some (likely some), which will return true if any item in an iterable returns true for a given condition.

 function uncompletedNotes(notes) {
  
  let result = []
      
      notes.forEach(element => {
        if(element.todos.some(todo => todo.done === false)) {
          result.push(element);
        }
      });

   return result;

  }

Todos is also an array, so you'd have to iterate over that one as well

'todos' is an array as well. You need to iterate over it. One way to do that is to use the find function as shown below.

function uncompletedNotes(notes) {
  
  let result = []
  
  notes.forEach(element => {
    if(element.todos.find(todo => todo.done === false)) {
      result.push(element);
    }
  });

  return result;

}

const notes = [
  {
    id: 1,
    description: 'Workout program',
    todos: [
      {
        id: 1,
        name: 'Push ups - 10 x 3',
        done: false
      },
      {
        id: 2,
        name: 'Abdominals - 20 x 3',
        done: true
      },
      {
        id: 3,
        name: 'Tapis Roulant - 15min',
        done: true
      }
    ]
  },
  {
    id: 2,
    description: 'Front-end Roadmap',
    todos: [
      {
        id: 1,
        name: 'Learn HTML',
        done: true
      },
      {
        id: 2,
        name: 'Learn CSS',
        done: true
      },
      {
        id: 3,
        name: 'Learn JavaScript',
        done: true
      },
      {
        id: 4,
        name: 'Learn Angular',
        done: true
      }
    ]
  }
]

const notesInProgress = uncompletedNotes(notes);
console.log('All notes: ', notes);
console.log('Notes In Progress: ', notesInProgress);

For each notes iterate over the todos

  • for each todos
    • check if its 'done'==true
    • if all the 'done's are not true, then push the note to inProgress array.

Firstly! Nice exercise. Second i change only a little bit in you foreach loop. And use filter.

  notes.forEach(element => {
    const open = element.todos.filter(t => t.done === false)    
    result.push(...open)
  });

function uncompletedNotes(notes) {
  
  let result = []
  
  notes.forEach(element => {
    const open = element.todos.filter(t => t.done === false)    
    result.push(...open)
  });
  return result;
}

const notes = [
  {
    id: 1,
    description: 'Workout program',
    todos: [
      {
        id: 1,
        name: 'Push ups - 10 x 3',
        done: false
      },
      {
        id: 2,
        name: 'Abdominals - 20 x 3',
        done: true
      },
      {
        id: 3,
        name: 'Tapis Roulant - 15min',
        done: true
      }
    ]
  },
  {
    id: 2,
    description: 'Front-end Roadmap',
    todos: [
      {
        id: 1,
        name: 'Learn HTML',
        done: true
      },
      {
        id: 2,
        name: 'Learn CSS',
        done: true
      },
      {
        id: 3,
        name: 'Learn JavaScript',
        done: true
      },
      {
        id: 4,
        name: 'Learn Angular',
        done: true
      }
    ]
  }
]

const notesInProgress = uncompletedNotes(notes);
console.log('All notes: ', notes);
console.log('Notes In Progress: ', notesInProgress);

In your .forEach loop, you have this line:

if(element.todos.done == false) {

Since todos is an array, you would need to check whether any of the array todos have their done property set to false. There are a few ways you can do this, but the way I've implemented in the full code at the end is using the Array.filter method:

    let todos = element.todos.filter(todo => !todo.done);
    // If todos contains at least one task, it is incomplete...
    if (todos.length > 0) {
      // ... so add it to the result array (which we return shortly)
      result.push(element);
    }

See the full code below for example:

function uncompletedNotes(notes) {
  let result = []
  notes.forEach(element => {
    let todos = element.todos.filter(todo => !todo.done);
    if (todos.length > 0) {
      result.push(element);
    }
  });
  return result;
}

const notes = [{
    id: 1,
    description: 'Workout program',
    todos: [{
        id: 1,
        name: 'Push ups - 10 x 3',
        done: false
      },
      {
        id: 2,
        name: 'Abdominals - 20 x 3',
        done: true
      },
      {
        id: 3,
        name: 'Tapis Roulant - 15min',
        done: true
      }
    ]
  },
  {
    id: 2,
    description: 'Front-end Roadmap',
    todos: [{
        id: 1,
        name: 'Learn HTML',
        done: true
      },
      {
        id: 2,
        name: 'Learn CSS',
        done: true
      },
      {
        id: 3,
        name: 'Learn JavaScript',
        done: true
      },
      {
        id: 4,
        name: 'Learn Angular',
        done: true
      }
    ]
  }
]

const notesInProgress = uncompletedNotes(notes);
console.log('All notes:', notes);
console.log('Notes In Progress:', notesInProgress);

Related