Compare two arrays in length: skip empty values

I have a form with 4 inputs (there may be many more) where the user can put a number or nothing. The only rule is that if you put a number in the input, you cannot send if the same number is on another input (without duplicates). You can send as many empty input as you want.

To check the input, I compare the length of the array of all inputs with the same array with only unique values. If they are the same length, everything is in order. I need to improve the code, because now it only works if the user enters all the input fields. If some inputs are empty, they are considered in an array with a unique value, since they all have a value of "" as a value. So, if the user enters only one number, I get that the length of this array is 4, and the array is unique - 2, but it should be 1 and 1 (skipping empty elements).

I was thinking about using splice() in arr , but is this the best way to do this check? ** EDIT: I applied splicing, but if the array is ('1', '', ''), my code gives me ('1', '') instead of just (1), as I would expect ... * * This is because splicing removes the element and changes the length of the array, so the for loop indicates the wrong index. Any ideas? HTML:

 <div class="sez-form"> <fieldset> <legend>Messaggi inclusi</legend> <div class="percheckbox"> <input class="checkseq" type="checkbox" value="1" name="messaggio[0]"> Prova di messaggio che scorre<br> <label>Ordine: </label> <input class="seq" type="text" name="ordine[0]" maxlength="2" size="2"> </div> <div class="percheckbox"> <input class="checkseq" type="checkbox" value="3" name="messaggio[1]"> Titoli di film<br> <label>Ordine: </label> <input class="seq" type="text" name="ordine[1]" maxlength="2" size="2"> </div> <div class="percheckbox"> <input class="checkseq" type="checkbox" value="6" name="messaggio[2]"> Prova a testo fisso<br> <label>Ordine: </label> <input class="seq" type="text" name="ordine[2]" maxlength="2" size="2"> </div> <br style="clear: both;"> </fieldset> </div> 

JAVASCRIPT:

 function uniqueArray(arr) { return $.grep(arr,function(v,k) { return $.inArray(v,arr) === k; }); } $(document).ready(function() { $('#invia').click(function(e) { e.preventDefault(); var arr = $(".seq").map(function(){ return $(this).val(); }).toArray(); var empty = $(".seq").filter(function() { return this.value == ""; }) for (index = 0; index < arr.length; ++index) { if (arr[index]=='') { new_arr = arr.splice([index],1); } console.log(arr); } if(empty.length == $('.seq').length) { alert('Non hai scelto alcun messaggio per il workflow. Correggi per procedere.'); } else if(uniqueArray(arr).length != $('.seq').length) { console.log(uniqueArray(arr)); alert('Ci sono voci duplicate nella sequenza. Correggi per procedere.'); } else if($('#dt_from').val()=='__/__/____ __:__') { alert('Scegli data e ora di inizio validit\u00E0 per il workflow'); } else if($('#dt_to').val()=='__/__/____ __:__') { alert('Scegli data e ora di fine validit\u00E0 per il workflow'); } else { ajaxSubmit(); } }); }); 
+1
source share
3 answers

Use a hash to track values ​​as you repeat. This example simply returns true or false , but you can also scan the entire array and return duplicate values.

 function uniquifyArray(ary) { var seen = {}; var isUnique = true; /* iterate backwards since the array length will change as elements are removed */ for (var i=ary.length; i--;) { /* remove blank/undefined */ if (typeof ary[i] === 'undefined' || ary[i] === '') { ary.splice(i,1); } else { /* check if this value has already been seen */ if (ary[i] in seen) { isUnique = false; ary.splice(i,1); } else { seen[ary[i]]=true; } } } ary = ary.sort(); return isUnique; } var test = [ '1','2','','','3','4','1' ]; uniquifyArray(test); // returns false, test = [ '1','2','3','4' ] test = [ '1','2','','' ] uniquifyArray(test); //true, test = ['1','2'] 
0
source

Perhaps I do not understand what you are trying to do, but why you cannot do it very simply with something like:

 $('#invia').click(function(e) { e.preventDefault(); var unique = [], nonunique = []; $(".seq").each(function(index){ var val = $(this).val(); if (val !== "") { if ($.inArray(val, unique) !== -1) { nonunique.push(val); } else { unique.push(val); } } }); // If unique and nonunique are empty, all inputs were blank // else if nonunique is empty, inputs are valid and in unique }); 
+1
source

Here is another way to handle this. Here is a working JSFiddle. And here is the code:

 $(function() { $("#submit").click(function() { //build a profile of the inputs var inputs = []; var values = []; var dups = false; //track duplicates on pass 1 $(".seq").each(function(i, el) { var empty = (el.value == ""); //check if empty var exists = (!empty && $.grep(inputs, function(item, index) { return (item.Value === el.value); }).length > 0); //check if exists dups = (dups || exists); //track dups //add the new input item var obj = { Element: el, Value: el.value, Empty: empty, Exists: exists }; inputs.push(obj); //conditionally add the sorting value if (!empty && !exists) values.push(el.value); }); //Validate the inputs. If there are duplicates, don't submit $(".seq").css("background-color", "white"); //clear errors if (dups) { $(inputs).each(function(i, el) { if (el.Exists) el.Element.style.backgroundColor = "red"; }); } else { values = values.sort(); alert(values); } }); }); 

Using this method, at the end you have an array - inputs - of all elements with statuses so that you can handle errors in certain fields. In my example, the error fields turn red.

In alert , you have a sorted array of valid values.

+1
source

Source: https://habr.com/ru/post/1236323/


All Articles