Skip to content Skip to sidebar Skip to footer

Check Duplicate Values Between Multiple Inputs And Show Error Message

I have list of inputs from an array created via ng-repeat. I want to check if there are any duplicated values in them. If any duplicated value found it shows an error message. I fo

Solution 1:

It doesn't work because you have the wrong key name in the sort function and you are trying to use a nested object.

Just modifying it to this will get it to work with the first object in the array. You would need to iterate through each object though to get it to work for all of them.

$scope.verifyDuplicate = function() {
    var sorted, i;

    sorted = $scope.csTagGrp[0].csTags.concat().sort(function(a, b) {
      if (a.keys > b.keys) return1;
      if (a.keys < b.keys) return -1;
      return0;
    });
    for (i = 0; i < $scope.csTagGrp[0].csTags.length; i++) {
      sorted[i].isDuplicate = ((sorted[i - 1] && sorted[i - 1].keys == sorted[i].keys) || (sorted[i + 1] && sorted[i + 1].keys == sorted[i].keys));
    }
  };

Because you are using a nested object, this becomes a slightly more complicated problem to solve. You have an array of objects that also have arrays in them. If you (can) put everything into a flatter object, it's simple.

The csTagGrp[0] tells it to access the first object in the csTagGrp array, which is:

{"csTagTitle":"Action","csTags":[{"keys":"1","tags":"Quick Win"},{"keys":"2","tags":"follow up with respondent"},{"keys":"3","tags":"process imporvement"},{"keys":"4","tags":"Large Fix"},{"keys":"5","tags":"use in presentation"}]}

So now sorted accesses the csTags array in the object at [0] in the csTagGrp array and performs the sort on all the keys in that array. So far so good. But with the object structure you have here, you need to iterate through both arrays (that is, all the objects in csTagGrp, as well as each csTags array in each csTagGrp object) and perform a sort on ALL of them. This usually involves multiple for loops.

So to accomplish this, I concat'ed all the csTags arrays (using a for loop) into a new array, preSort, which then gets passed to sort. This gives us what we need (one flat array) to check all the csTags arrays for duplicates.

  $scope.verifyDuplicate = function() {
    var preSort = [],sorted, i, c = $scope.csTagGrp;

    for(i = 0; i < c.length; i++) {
      preSort = preSort.concat(c[i].csTags);  
    }

    sorted = preSort.concat().sort(function(a, b) {
      if (a.keys > b.keys) return1;
      if (a.keys < b.keys) return-1;
      return0;
    });
    console.log(sorted)
    for (i = 0; i < preSort.length; i++) {
      sorted[i].isDuplicate = ((sorted[i - 1] && sorted[i - 1].keys == sorted[i].keys) || (sorted[i + 1] && sorted[i + 1].keys == sorted[i].keys));
    }
  };
});

Here is the working demo.

Solution 2:

Unfortunately there are quite a lot of problems, but I believe none are impossible to overcome. The biggest problem lies in the difference in data structures. In the original fiddle, the data is in a simple array:

$scope.persons= [
    {name:1},
    {name:2},
    {name:3}
];

whereas in your plunker, the data is (as you already mentioned) quite a lot more nested:

$scope.csTagGrp = [{
  "csTagTitle": "Action",
  "csTags": [{
    "keys": "1",
    "tags": "Quick Win"
  }, {
    "keys": "2",
    "tags": "follow up with respondent"
  }] // snipped contents for brevity
}, {
  "csTagTitle": "Topicality",
  "csTags": [{
    "keys": "6",
    "tags": "Root cause"
  }, {
    "keys": "7",
    "tags": "Symptom"
  }] // snipped contents
}, {
  // snipped rest for brevity
}]

...so you just can't use something like this (from your plunker):

sorted = $scope.csTagGrp.csTags.concat().sort(function(a, b) {
  if (a.name > b.name) return1;
  if (a.name < b.name) return -1;
  return0;
});
for (i = 0; i < $scope.csTagGrp.csTags.length; i++) {
  sorted[i].isDuplicate = ((sorted[i - 1] && sorted[i - 1].name == sorted[i].name) || (sorted[i + 1] && sorted[i + 1].name == sorted[i].name));
}

And the problems are:

  • $scope.csTagGrp is an Array of objects (that each have a csTags property), it is not an Object with a csTags property
    • thus, $scope.csTagGrp.csTags is undefined -> trying to invoke concat() on undefined doesn't - naturally - work
    • you could access csTags property within a single object inside $scope.csTagGrp, for example like this: sorted = $scope.csTagGrp[0].csTags.concat().sort(function(a, b) { but then again, that would sort only the first object within $scope.csTagGrp, and not all
  • which leads us to the next problem: the original duplicate verification works, because it just sorts a flat array. With your nested array, this approach would only work within a single group, not throughout all objects in $scope.csTagGrp

    • of course this might even be your desired functionality, and in that case you'd need only minor corrections (do the sorting and comparations in a loop, each object within $scope.csTagGrp separately, and that's pretty much it)
    • but if (and I suspect when) you would like to detect duplicates within each of the objects, you will need to come up with a new way to extract and sort the csTags:

      1. extract the csTags array from each object
      2. create a flat array of all the csTags arrays, i.e. looking like this:

        [
            {"keys": "1", "tags": "Quick Win"},
            {"keys": "2", "tags": "follow up with respondent"},
            // and so on from the first object
            {"keys": "6", "tags": "Root cause"},
            {"keys": "7", "tags": "Symptom"},
            // and so on from the second object, andall the rest as well
        ]
        
      3. sort that flat array
      4. do the duplicate comparisons on the sorted array
  • and that leaves us with the final, and I guess simplest problem: you forgot to change the comparison property from the original (name) to what you have (keys)

Hopefully this helps you to move ahead!

Post a Comment for "Check Duplicate Values Between Multiple Inputs And Show Error Message"