lodash/underscore;比较两个对象并删除重复项
lodash/underscore; compare two objects and remove duplicates
如下图所示,我返回了一些 json data
三个对象;每个都包含一个客户 ID => 数据。
exact_match : {104}
match_4 : {104, 103}
match_2 : {104, 103, 68}
我如何"trim"或删除基于之前对象的重复对象?类似于:
exact_match : {104}
match_4 : {103}
match_2 : {68}
我尝试了 _.difference 但没有成功(也许是因为它是针对数组而不是对象?):
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),
任何帮助将不胜感激:)
更新
我需要返回值具有相同的对象数据而不是新数组:)
您似乎想要区分密钥(或者更确切地说,它会很有效 — _.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]]
我会创建一个名为 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)
returns true
,则删除密钥。
您可以乱用 lodash/underscore 方法,但这些方法可能效率低下,具体取决于您如何使用它们(以及它们的实现方式),并且这应该在线性时间内运行。
对于您的特定用例,完整的解决方案看起来像是:
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's already found
if (alreadyFound(id)) {
delete object[id];
}
}
}
谢谢你们的回答,非常感谢你们的宝贵时间。
我进一步搜索并发现 this post 是 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>
如下图所示,我返回了一些 json data
三个对象;每个都包含一个客户 ID => 数据。
exact_match : {104}
match_4 : {104, 103}
match_2 : {104, 103, 68}
我如何"trim"或删除基于之前对象的重复对象?类似于:
exact_match : {104}
match_4 : {103}
match_2 : {68}
我尝试了 _.difference 但没有成功(也许是因为它是针对数组而不是对象?):
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),
任何帮助将不胜感激:)
更新
我需要返回值具有相同的对象数据而不是新数组:)
您似乎想要区分密钥(或者更确切地说,它会很有效 — _.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]]
我会创建一个名为 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)
returns true
,则删除密钥。
您可以乱用 lodash/underscore 方法,但这些方法可能效率低下,具体取决于您如何使用它们(以及它们的实现方式),并且这应该在线性时间内运行。
对于您的特定用例,完整的解决方案看起来像是:
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's already found
if (alreadyFound(id)) {
delete object[id];
}
}
}
谢谢你们的回答,非常感谢你们的宝贵时间。
我进一步搜索并发现 this post 是 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>