Lodash / underline; compare two objects and remove duplicates

As you can see in the image below, I have returned json datawith three objects; each contains id => customer identifiers.

Returned json data

exact_match : {104}
match_4 :  {104, 103}
match_2 :  {104, 103, 68}

How can I “crop” or delete duplicate objects based on previous ones? sort of:

exact_match : {104}
match_4 :  {103}
match_2 :  {68}

I tried _. difference , but it didn’t work (maybe because these are not arrays, but objects?):

var exact_match = data.exact_match,
    match_four_digits = _.difference(data.match_4, data.exact_match),
    match_two_digits = _.difference(data.match_2, data.exact_match, data.match_4),

Any help would be appreciated :)

Update

I need the return value to have the same object data instead of a new array :)

+4
source share
3 answers

, , , .

Lodash, ;

var data = {
  exact_match: {
    104: {
      supplier_id: 104
    }
  },
  match_four_digits: {
    104: {
      supplier_id: 104
    },
    68: {
      supplier_id: 68
    }
  },
  match_two_digits: {
    104: {
      supplier_id: 104
    },
    68: {
      supplier_id: 68
    },
    103: {
      supplier_id: 103
    },
    999: {
      supplier_id: 999
    }
  }
};

var arr_match_four_digits = _.difference(_.keys(data.match_four_digits), _.keys(data.exact_match));
var arr_match_two_digits = _.difference(_.keys(data.match_two_digits), _.keys(data.match_four_digits), _.keys(data.exact_match));



$('#output1').html(JSON.stringify(data));
$('#output2').html(JSON.stringify(_.pick(data.match_four_digits, arr_match_four_digits)));
$('#output3').html(JSON.stringify(_.pick(data.match_two_digits, arr_match_two_digits)));
<script src="https://cdn.rawgit.com/lodash/lodash/3.3.1/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

data
<pre><code><div id="output1"></div></code></pre>
arr_match_four_digits
<pre><code><div id="output2"></div></code></pre>
match_two_digits
<pre><code><div id="output3"></div></code></pre>
Hide result
+1

, (, - _.keys)

_.difference(
  _.keys({104: 1, 102: 3, 101: 0}), // ["104", "102", "101"]
  _.keys({104: 1, 102: 3}) // ["104", "102"]
)
// [ "101" ]

, (_.pairs):

_.difference(
  _.pairs({104: 1, 102: 3, 101: 0}), // [["104",1], ["102",3], ["101",0]]
  _.pairs({104: 1, 102: 2}) // [["104",1], ["102",2]]
)
// [["102", 3], ["101", 0]]
+8

unique, . var unique = {};, , unique. unique, , , .

alreadyFound:

var alreadyFound = function (key) {
  if (!(key in unique)) {
    unique[key] = true;
    return false;
  }
  return true;
};

alreadyFound(key) key , alreadyFound(key) true.

You can use lodash / underscore methods, but they can be ineffective depending on how you use them (and how they are implemented), and this should work in linear time.

It seems like for your specific use case, a complete solution would be something like:

var unique = {};
// Assume I copy and pasted alreadyFound here
var alreadyFound = ...;
for (var object in data) {
  // Iterate through ids in each object in data
  for (var id in object) {
    // Remove this entry if it already found
    if (alreadyFound(id)) {
      delete object[id];
    }
  }
}
+1
source

All Articles