简体   繁体   中英

How to remove array using splice method

I've created (3) lists. What I'm trying to do:

-When the checkbox is checked, push values into the mainArray (which I've gotten to work)

-When the checkbox unchecked, remove values from the mainArray.

For example: If input A is unchecked, remove [6, 7, 8, 9, 10] from the mainArray.

Any help or input here would be greatly appreciated! Cheers.

 const a = document.querySelector('.input-1') const b = document.querySelector('.input-2') const c = document.querySelector('.input-3') const list = [1, 2, 3, 4, 5]; const list2 = [6, 7, 8, 9, 10]; const list3 = [11, 12, 13, 14, 15]; const mainArray = []; a.addEventListener('change', function(e) { if (a.checked) { mainArray.push(list) console.log(mainArray) } else if (!a.checked) { let index = mainArray.indexOf(list) if (index != -1) { mainArray.splice(index) console.log(mainArray) } } }); b.addEventListener('change', function(e) { if (b.checked) { mainArray.push(list2) console.log(mainArray) } else if (!b.checked) { let index = mainArray.indexOf(list2) if (index != -1) { mainArray.splice(index) console.log(mainArray) } } }) c.addEventListener('change', function(e) { if (c.checked) { mainArray.push(list3) console.log(mainArray) } else if (!c.checked) { let index = mainArray.indexOf(list3) if (index != -1) { list3.splice(index) console.log(mainArray) } } })
 <input class="input-1" type="checkbox" value = "a"> A <input class="input-2" type="checkbox" value = "b"> B <input class="input-3" type="checkbox" value = "c"> C

Any help, or input here would be appreciated.

Quick and dirty way to accomplish the same thing. Each time you click a checkbox, it recalculates mainArray from scratch, using the currently selected checkboxes and their data-list attributes to build it.

 [...document.querySelectorAll(".listy")].forEach(input => { input.addEventListener('change', (e) => { const mainArray = [...document.querySelectorAll(".listy:checked")].flatMap(el => JSON.parse(el.dataset.list)); console.log(mainArray); }); });
 <input class="listy" type="checkbox" value = "a" data-list="[1,2,3,4,5]"> A <input class="listy" type="checkbox" value = "b" data-list="[6,7,8,9,10]"> B <input class="listy" type="checkbox" value = "c" data-list="[11,12,13,14,15]"> C

You need to delete only one, so make sure you pass the second param.

mainArray.splice(index, 1);

You can also make this more generic by accessing a list at the index of the letter eg a = 0, b = 1, c = 2, etc... by normalizing the character codes into an index.

Full example

 const mainArray = []; const lists = [ [1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15] ]; const handleClick = (e) => { const input = e.target; const listIndex = input.value.charCodeAt(0) - 97; const foundList = lists[listIndex]; if (input.checked) { mainArray.push(foundList); } else { let index = mainArray.indexOf(foundList); if (index !== -1) { mainArray.splice(index, 1); } } console.log(JSON.stringify(mainArray)); }; document.querySelectorAll('.list') .forEach(el => el.addEventListener('input', handleClick));
 <input class="list" type="checkbox" value="a"> A <input class="list" type="checkbox" value="b"> B <input class="list" type="checkbox" value="c"> C

A better way to achieve this would be to make the mail list mutable and just replace the value. When updating the value, just look at the current selections and reduce the lists.

 let mainList = []; // Make this mutable... const subLists = [ [1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15] ]; const syncChoices = (inputs, lists) => [...inputs].reduce((acc, { checked }, index) => checked ? [...acc, ...lists[index]] : acc, []); const handleClick = (e) => { mainList = syncChoices(document.querySelectorAll('.list'), subLists); // Set console.log(JSON.stringify(mainList)); // Print the list }; document.querySelectorAll('.list') .forEach(el => el.addEventListener('input', handleClick));
 .as-console-wrapper { max-height: 4em !important; }
 <input type="checkbox" class="list" data-index="0"> A <input type="checkbox" class="list" data-index="1"> B <input type="checkbox" class="list" data-index="2"> C

You should be referencing mainArray instead of list .

 const a = document.querySelector('.input-1') const b = document.querySelector('.input-2') const c = document.querySelector('.input-3') const list = [1, 2, 3, 4, 5]; const list2 = [6, 7, 8, 9, 10]; const list3 = [11, 12, 13, 14, 15]; const mainArray = []; a.addEventListener('change', function(e) { if (a.checked) { mainArray.push(list) console.log(mainArray) } else if (!a.checked) { let index = mainArray.indexOf(list) if (index != -1) { mainArray.splice(index) console.log(mainArray) } } }); b.addEventListener('change', function(e) { if (b.checked) { mainArray.push(list2) console.log(mainArray) } else if (!b.checked) { let index = mainArray.indexOf(list2) if (index != -1) { mainArray.splice(index) console.log(mainArray) } } }) c.addEventListener('change', function(e) { if (c.checked) { mainArray.push(list3) console.log(mainArray) } else if (!c.checked) { let index = mainArray.indexOf(list3) if (index != -1) { mainArray.splice(index) console.log(mainArray) } } })
 <input class="input-1" type="checkbox" value = "a"> A <input class="input-2" type="checkbox" value = "b"> B <input class="input-3" type="checkbox" value = "c"> C

Here is another way of doing the same:

 const arr = [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]], cbs=document.querySelectorAll("input[type=checkbox]") document.body.onchange=()=> console.log(arr.filter((_,i)=> cbs[i].checked).flat() );
 <label><input type="checkbox"> A</label> <label><input type="checkbox"> B</label> <label><input type="checkbox"> C</label>

In a real use case you will probably need to limit the selector document.body to the actual container surrounding the checkboxes.

If you really, really want to do it with .splice() then maybe the following could be a way to do it:

 const arr = [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]], cbs=document.querySelectorAll("input[type=checkbox]"); document.body.onchange=()=>{ for(var res=arr.slice(0),i=cbs.length;i--;) if(!cbs[i].checked) res.splice(i,1); console.log(res.flat()); };
 <label><input type="checkbox"> A</label> <label><input type="checkbox"> B</label> <label><input type="checkbox"> C</label>

In order to preserve the original array I create a shallow copy first with .slice(0) . The for loop is then made to count down from the highest index to zero, splice ing away an element from the res -array whenever the associated cbs -element is not checked.

Your logic is right but the way you're using arr.splice() is wrong.

For it to work in your case you should give a second argument to splice to inform how many elements you wish to remove

Ex:

 let arr = [1,2,3,4,5,6,7,8,9] arr.splice(3,10)

This will remove all elements starting from index 3 in the array.

Since in your case you pre defined the number of elements in each array you wish to remove i believe using this method will be the simplest way.

There are also other ways to use splice() where you can select the exact element you wish to remove.

Here's the link, everything u need to know about splice will be here ,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM