Home > Software engineering >  alternative to an if else inside a for loop
alternative to an if else inside a for loop

Time:02-09

Currently my code is working properly but I would like to have an alternate version of my code example without the if else. I would like to use functional programming with functions such as find but I am a bit stuck with the second loop inside the first loop.

The aim of the code is to update the array of tasks when either a task or a subTask when their id matches a given id. The updated task (or subTask) should remain at the same position in the array of tasks (or in the array of subTasks)

To simply things:

const idToSearch; let index; let subIndex; 
for (const task of tasks){ 
  if (task.id === idToSearch && stuff to validate task){
     const task = update(task, parameters);
     tasks.splice(index, 1, task);  
  }
  else if (task.hasSubTasks){
     for (const subTask of task.subTasks){
        if (subTask.id = idToSearch && stuff to validate subtask){
           const subTask = update(subTask, parameters);
           task.subTasks.splice(subIndex, 1, subTask);
           tasks.splice(index,1,task);
           return;
        }
        subIndex  ;
     }  

 }   
 index  ; 
}

Could you give me some pointers?

Edit: I just reformulated the question, I was not precise enough.

Edit2: the update function is pure. It takes the task (or subTask) and parameters and returns the updated task / subTask.

CodePudding user response:

How about something like this?

const updateById = (id) => {
    let task = tasks.find(t => t.id == id);
    if (task) {
        return update(task);
    }
    task = tasks.map(t => t.subTasks).flat().find(t => t.id == id);
    if (task) {
        return update(task);
    }
}

This code uses the find function, checking the id against the task updating the first it finds. If it can't find it, it uses the map function to return all the subtasks of each (making an array of arrays), then calls flat() on it to make it one continuous array before using find as above.

Edit:

You keep asking about returning or updating the array. You don't need to, as JavaScript objects only exist in one location. To update them in one place updates them everywhere, unless you break the reference to them.

Here is an example where I update one task but logging the original tasks array shows the newly updated task.

const tasks = [
  {
    id: 1,
    name: "one",
    val: 1,
    subtasks: []
  },
  {
    id: 2,
    name: "two",
    val: 2,
    subtasks: []
  },
  {
    id: 3,
    name: "three",
    val: 3,
    subtasks: [{
      id: 4,
      name: "four",
      val: 4,
    }]
  },
];

const update = (task) => {
  task.val  = 10;
}

const updateById = (id) => {
  let task = tasks.find(t => t.id == id);
  if (task) {
    update(task);
  }
  task = tasks.map(t => t.subtasks).flat().find(t => t.id == id);
  if (task) {
    update(task);
  }
}

updateById(4);

// Prints tasks and also shows task id = 4 with a value of 14
console.log(tasks);

Note that the task with an ID of 4 which is updated is modified in the tasks array.

If you are asking something different (which I think you might be) along the lines of:

How can I create a new array with the modified data in it, then the code will be almost the same, but we must clone the array at the start of our function.

Please note I have added a tasks argument to the function.

const tasks = [
  {
    id: 1,
    name: "one",
    val: 1,
    subtasks: []
  },
  {
    id: 2,
    name: "two",
    val: 2,
    subtasks: []
  },
  {
    id: 3,
    name: "three",
    val: 3,
    subtasks: [{
      id: 4,
      name: "four",
      val: 4,
    }]
  },
];

const update = (task) => {
  task.val  = 10;
}

const updateById = (tasks, id) => {
  // Perform a deep clone of the array. There are many ways to do this, and much better stackoverflow answers than mine on how they work
  // It is this action that "breaks the reference" to the original array and its objects
  tasks = JSON.parse(JSON.stringify(tasks));
  let task = tasks.find(t => t.id == id);
  if (task) {
    update(task);
    return tasks;
  }
  task = tasks.map(t => t.subtasks).flat().find(t => t.id == id);
  if (task) {
    update(task);
    return tasks;
  }
}

const newTasks = updateById(tasks, 4);

console.log({newTasks}, {oldTasks: tasks});

In this example, the newTasks is updated while leaving the original tasks intact.

  •  Tags:  
  • Related