4

I have an object that has multiple keys and each of these keys has an array storing multiple elements. I want to be able to remove a specified element from the key's array.

I have tried using the delete keyword as well as the filter method, but I have been unsuccessful. I'm a total newbie to JS so I appreciate any assistance. Also, I want to do this using ONLY JavaScript, no libraries.

Here is the code where I am creating my object:

function add(task, weekdayDue) {
   let capitalWeekday = weekdayDue.charAt(0).toUpperCase() + 
      weekdayDue.slice(1);
   if (toDoList[capitalWeekday] === undefined) {
      let subArr = [];
      toDoList[capitalWeekday] = subArr.concat(task); 
   } else {
      toDoList[capitalWeekday].push(task);
     }
   }

and here is the code as I have it now. Clearly it is not producing the correct result:

 function remove(task, weekdayDue) {
    let capitalWeekday = weekdayDue.charAt(0).toUpperCase() + 
    weekdayDue.slice(1);
    delete toDoList.capitalWeekday[task] 
    //the below code is working; i want to send this to another 
     array
    if (archivedList[capitalWeekday] === undefined) {
       let subArr = [];
       archivedList[capitalWeekday] = subArr.concat(task);
     } else {
       archivedList[capitalWeekday].push(task);
     }
   };


 add('laundry', 'monday');
 add('wash car', 'monday');
 add ('vacuum', 'tuesday');
 add('run errands', 'wednesday');
 add('grocery shopping', 'wednesday');

 // the output is:  { Monday: [ 'laundry', 'wash car' ],
 Tuesday: [ 'vacuum' ],
 Wednesday: [ 'run errands', 'grocery shopping' ] }

Then let's say I want to remove 'wash car' from Monday I was trying:

 remove('wash car', 'monday');
 console.log(toDoList)

// The output is an empty object {}
S.W
  • 53
  • 6
  • This could be better understood if you add an example of the structure you have and the expected output after you call `remove()`. – Shidersz May 12 '19 at 23:55
  • What do you mean by "result" and "output" - which variable(s) are you talking about because your functions don't return or display anything. – James May 12 '19 at 23:57
  • Can you please add some example input and output? – Jack Bashford May 12 '19 at 23:59
  • I don't know what the exact structure of your objects are but how about for each key find its array and for each element in that array check if it's the element you want to remove. [If it is remove it with splice](https://stackoverflow.com/questions/5767325/how-do-i-remove-a-particular-element-from-an-array-in-javascript) – David May 13 '19 at 00:00
  • Yes sorry about that. – S.W May 13 '19 at 00:00

3 Answers3

2

I personally would refactor a bit your code, but I've worked a bit around it to fix some issues.

First of all, you shouldn't use delete for your scenario, because it will reset the item at the nth position of the array with the default value, which is undefined. Usually, for that kind of operations, since you deal with strings, you rather take a look at the first occurrence of your item in the array, take its index, and use splice (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) to actually remove the item from the array.

In this way, you end up with a clean array without invalid items in it.

Below is the working code (with the mentioned fixes) that does what you asked. As a side note, I would suggest you to avoid working with strings for such purposes, but I would rather tackle objects with unique ids, so that it's significantly easier to keep track of them between arrays and objects.

Additionally, there are some cases that you didn't think about, for instance I can think about calling remove by giving an invalid task, so you may work a bit around the code below to handle the case where taskIndex is -1 (meaning that no item was found with that index).

var toDoList = {}, archivedList = {};

function add(task, weekdayDue) {
 let capitalWeekday = weekdayDue.charAt(0).toUpperCase() + weekdayDue.slice(1);
 if (toDoList[capitalWeekday] === undefined) {
    let subArr = [];
    toDoList[capitalWeekday] = subArr.concat(task); 
 } else {
  toDoList[capitalWeekday].push(task);
 }
}

function remove(task, weekdayDue) {
  let capitalWeekday = weekdayDue.charAt(0).toUpperCase() + weekdayDue.slice(1);
  let taskIndex = toDoList[capitalWeekday].indexOf(task);
  toDoList[capitalWeekday].splice(taskIndex, 1);
  //delete toDoList[capitalWeekday][taskIndex];
  if (archivedList[capitalWeekday] === undefined) {
   let subArr = [];
   archivedList[capitalWeekday] = subArr.concat(task);
 } else {
   archivedList[capitalWeekday].push(task);
 }
};

add('test', 'monday');
add('wash car', 'monday');
remove('wash car', 'monday');

console.log(toDoList);
console.log(archivedList);
briosheje
  • 6,538
  • 2
  • 31
  • 48
  • You raised some valid points, but using `Array.filter` will be easier and cleaner than searching for the index and making the `splice`. And you achieve the same results :) – Bruno Monteiro May 13 '19 at 22:13
  • Filter is not as performant and creates a new array. Since you need to remove just One Item, filtering is not the best solution, to me ;) – briosheje May 14 '19 at 04:43
1

You are on the right path. Maybe the trouble you had with filter is because filter will return a new Array and not modify the current one. You could update your remove function and replace the line:

delete toDoList.capitalWeekday[task]

with

toDoList.capitalWeekday = toDoList.capitalWeekday.filter((item) => {return item !== task});

Bruno Monteiro
  • 2,618
  • 1
  • 19
  • 36
  • This is great. Thank you; when I was attempting to use filter earlier, I don't think I was filtering out the right element, but this is super helpful. Appreciated! – S.W May 13 '19 at 00:07
  • You are welcome, glad to know it helped you! If you consider this the right answer, please accept that to help me as well :) – Bruno Monteiro May 13 '19 at 00:45
1
function remove(task, weekdayDue) {
  let capitalWeekday = weekdayDue.charAt(0).toUpperCase() + 
  weekdayDue.slice(1);

  // Assign new array with all elements but task
  toDoList[capitalWeekday] = toDoList[capitalWeekday].filter(i => i !== task)
};

add('foo'...
add('bar'...

"{
  "Baz": [
    "Foo",
    "Bar"
  ]
}"

remove('foo'...

"{
  "Baz": [
    "Bar"
  ]
}"
blitzcom
  • 142
  • 1
  • 3