0

I have a function that will check a serialized form data if there are duplicates values in it.

    s = $('#multiselectForm').serialize();
    var x = [];
    var y = [];
    x = s.split("&");
    for (var i = x.length - 1; i >= 0; i--) {
        y.push(x[i].split("="));
    };
    var c = 0;
    var e = 0;
    for (var i = y.length - 1; i >= 0; i--) {
        if (y[i][1] == y[c][1]) {
            e++;
            $('.duplicateAlert').show();
        } else {
            $('.duplicateAlert').hide();
        };
        c++;
    };

Basically, what it does is split the string produced by the serialize() function and push the data into arrays.

The array I'm trying to parse looks like this:

Array [
    Array [
    0: 'my_field1',
    1: 'val1'
    ],

    Array [
    0: 'my_field2'
    1: 'val2'
    ],

    Array [
    0: 'my_field3'
    1: 'val1'
    ]
]

Are there any better ways to do the same task? Maybe even shorter?

9
  • 1
    If you want to check form controls for duplicate values, it would be far simpler (and probably hugely more efficient) to iterate over the form's elements collection and check the values directly. Commented Jun 3, 2015 at 0:25
  • your code does not find all duplicates Commented Jun 3, 2015 at 0:26
  • @RobG, no this is just a way to show the data format, they are all (nested) arrays Commented Jun 3, 2015 at 0:27
  • @Nikos yes it doesnt, i think it only finds the first one, then shows the .duplicateAlert for now, its fine for me since 1 duplicate is enough for me to show the user an error.. Commented Jun 3, 2015 at 0:27
  • 1
    Check stackoverflow.com/questions/9229645/… Commented Jun 3, 2015 at 0:28

3 Answers 3

2
  1. Create an empty array to hold the matches
  2. Loop through the array. On each iteration...
    1. Loop through the matches array and check if an item with the same value exists. If it does, set the matched flag.
    2. Check if the matched flag has been set
      1. if so, alert the user
      2. if not add the item to matches.

var array = [
    [ 'my_field1', 'val1' ],
    [ 'my_field2', 'val2' ],
    [ 'my_field3', 'val1' ],
    [ 'my_field4', 'val2' ],
    [ 'my_field5', 'val3' ]
], matches = [], match = false;

for(var i = 0, j = array.length; i < j; i++) {
    match = false;
    for(var k = 0, l = matches.length; k < l; k++) {
        if(matches[k][1] == array[i][1]) {
            match = true;
        }
    }
    if(match) alert('Duplicate!');
    else matches.push(array[i]);
}
Sign up to request clarification or add additional context in comments.

1 Comment

you can also use a hash for matches instead of an array and it will be faster to check for single match instead of looping through all the potential matches
1

If you have serialised data in the typical format like:

var data = 'foo=foo&bar=bar%26bar&blah=foo';

then you can check it for duplicates by getting the values between = and & and looking for dupes:

var seen = {};
var hasDupes = (data.match(/=[^&]+/g) || []).some(function(v){
    return v in seen || (seen[v] = true) && false;
});

console.log(hasDupes);  // true

The idea behind:

data.match(/=[^&]+/g) || []

is that match can return null if no matches are found, so if that happens the expression returns an empty array and the following call to some is called on the empty array (and returns false) rather than null, and hence doesn't throw the error that it would otherwise.

However, I still think it would be more efficient to check the form control values directly before serialising, rather than serialising the form then checking the result.

You can do that with a function like:

function checkDupValues(form) {
  var value,
      seen = {},
      controls = form.elements;

  for (var i=0, iLen=controls.length; i<iLen; i++) {
    // Might want to check type of control here and ignore buttons, etc.
    value = controls[i].value;

    // Ignore empty controls?
    if (value != '' && value in seen) {
      // have a duplicate value that is not ''
      alert('have dupes');

    } else {
      seen[value] = true;
    }
  }
}

Comments

0

Try this although its not much shorter:

var array = [
  [
    'my_field1',
    'val1'
  ],

  [
    'my_field2',
    'val2'
  ],

  [
    'my_field3',
    'val1'
  ]
]

var originals = [];
var duplicates = [];
for (a in array) {
  if (originals.indexOf(array[a][1] == -1)) {
    originals.push(array[a][1])
  } else {
    duplicates.push(array[a])
  }
}
alert('duplicates: ' + duplicates.join(', '));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.