Manish Jangir
Manish Jangir

Reputation: 5437

Find key of object for deep duplicate values using lodash

I've the following object:

var data = {
        2: [[1,2],[3,4,5],[6,7]],
        3: [[1,2],[3,4],[6,7]],
        4: [[1,2],[3,4,5],[6,7]],
        5: [[10,2],[3,4,5],[60,7]]
    }

I want the key 2 from the object because its value is duplicate in the array. There may be multiple duplicate keys like this.

I'm using lodash and tried the following but it wont work. Idon't having idea that how to start:

var dups = [];
_.map(formData,function(key, value){
    dups.push(value);
})
var duplicateArray = _.uniqWith(dups, _.isEqual);

Upvotes: 1

Views: 1354

Answers (2)

Dave Amit
Dave Amit

Reputation: 2319

This piece of code will match whole array irrespective of value sequence and value count. Consider following example

// Code goes here

Plunker: https://plnkr.co/edit/6jEByZHQhcwUopqqG4a2?p=preview (Click above link and open up console to see the result)

This will output ["2","3"] because "2" matches "4" and "3" matches "6".

// Code goes here

var data = {
  2: [ [1, 2], [3, 4, 5], [6, 7]],
  3: [[1, 2],[3, 4],[6, 7]],
  4: [[2, 1, 2, 1],[5, 3, 4],[6, 7]],
  5: [[10, 2],[3, 4, 5],[60, 7]],
  6: [[2, 1],[3, 4],[7, 6, 6]]
}

var dups = [];

//sorted and uniq buffer.
var buff = _.clone(data);
_.forEach(buff, function(lvl1, key) {
  buff[key] = _.map(lvl1, function(val) {
    return _.uniq(_.sortBy(val));
  });
});

_.forEach(buff, function(lvl1, key) {

  //Match each row with all others.
  //i.e. 2 with 3, 2 with 4, 2 with 5 ..... 6 with 5.
  _.forEach(buff, function(_lvl1, _key) {
    //Skip entries like 2 with 2, 3 with 3 and so on
    if (key !== _key) {
      console.log('compare ' + key + ' with ' + _key);
      var x = _.filter(_lvl1, function(val, index) {
        //Below condition are only true because ary are sorted and uniq.
              //If both must be of same len 
        return val.length === lvl1[index].length
               //If lenght of intersection of both values must be exactly equal 
               && _.intersection(val, lvl1[index]).length === val.length;
      });
      //If count matches and key and _key is not in dups
      // key and _key not in dups because we only want following:
      // 2 with 4 -> 2
      // 4 with 2 -> ignore! (we dont wanna include 4)
      //Hope it makes sense
      if (x.length === _lvl1.length && _.indexOf(dups, key) === -1 && _.indexOf(dups, _key) === -1) {
         //Mark the key as duplicate
         dups.push(key);
      }
    }

  });
});


console.log(dups)

Hope this helps!

Upvotes: 1

Slava Utesinov
Slava Utesinov

Reputation: 13508

I not sure that correct understand what you want, but as I assume answer will be look like that way (sample):

Javascript:

  var data = {
        2: [[1,2],[3,4,5],[6,7]],
        3: [[1,2],[3,4],[6,7]],
        4: [[1,2],[3,4,5],[6,7]],
        5: [[10,2],[3,4,5],[60,7]]
    };

  var find = function(input){
    var res = [];
    for(var prop in input){

      var start = false;
      for(var prop2 in input){
        if(start){
          var flag = JSON.stringify(input[prop]) == JSON.stringify(input[prop2]);
          if(flag){
            var flag3 = true;
            for(var j = 0; j < res.length; j++)
              if(JSON.stringify(input[prop]) == JSON.stringify(input[res[j]])){
                  flag3 = false
                  break;
              }
            if(flag3)
              res.push(prop);
            break;
          }
        }
        else{
         if(prop == prop2)
          start = true; 
        }
      }

    }
    return res;
  }

  var answer = find(data);

Upvotes: 0

Related Questions