根据相等对象的数量,消除相等对象并将最里面的 属性 递增 1
Eliminate equal objects and increment the innermost property by 1, based on the number of equal objects
我有以下代码消除数组中的相等对象,并将最里面的 属性 增加到相等对象的数量:
let SUPER = [{
"NAME1": {
"12": {
"10": 1
}
}
}, {
"NAME1": {
"12": {
"10": 1
}
}
}, {
"NAME1": {
"12": {
"10": 1
}
}
}, {
"NAME1": {
"12": {
"10": 1
}
}
}, {
"NAME1": {
"12": {
"11": 1
}
}
}],
FINAL = [];
for (let _super of SUPER) {
_super = JSON.stringify(_super);
let ii = 1,
ll = SUPER.length,
number = 1;
for (ii; ii < ll; ii++) {
let current = JSON.stringify(SUPER[ii]);
if (_super === current) {
SUPER.splice(ii, 1);
ii--;
number++;
}
}
if (number) {
FINAL.push(function clone(destination, source) {
destination = destination || {};
for (var prop in source) {
typeof source[prop] === 'object' && source[prop] !== null && source[prop] ? destination[prop] = clone({}, source[prop]) : destination[prop] = number;
}
return destination;
}({}, JSON.parse(_super)));
}
}
document.body.innerHTML = JSON.stringify(FINAL, null, 4);
如果没有两个或更多对象时的错误结果,并且几乎可以正常工作。结果应该是:
[{
"NAME1": {
"12": {
"10": 4
}
}
}, {
"NAME1": {
"12": {
"11": 1
}
}
}]
不是:
[{
"NAME1": {
"12": {
"10": 4
}
}
}, {
"NAME1": {
"12": {
"11": 2
}
}
}]
知道为什么吗?
给出的数据是示例数据。我不知道所有对象的实际属性。
问题:
- 它在除第一个迭代之外的所有迭代中都加 1
- 在 SUPER 丢失物品时使用 "for (let _super of SUPER) {"
我测试了更多 'unique' 个元素。如果您 运行 下面的代码,您将看到正确的结果。
var SUPER = [
{ "NAME1": { "12": { "21": 1 } } },
{ "NAME1": { "12": { "21": 1 } } },
{ "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "12": 1 } } },
{ "NAME1": { "12": { "11": 1 } } },
{ "NAME1": { "12": { "11": 1 } } }],
FINAL = [];
var firstPass = true;
for (var i = 0; i < SUPER.length; i++) {
_super = JSON.stringify(SUPER[i]);
let ii = 1,
ll = SUPER.length,
number = 1;
for (ii; ii < ll; ii++) {
let current = JSON.stringify(SUPER[ii]);
if (_super === current) {
SUPER.splice(ii, 1);
ii--;
number++;
}
}
if (number) {
FINAL.push(function clone(destination, source) {
destination = destination || {};
for (var prop in source) {
typeof source[prop] === 'object' && source[prop] !== null && source[prop] ? destination[prop] = clone({}, source[prop]) : (firstPass) ? destination[prop] = number : destination[prop] = number -1;
}
firstPass = false;
return destination;
}({}, JSON.parse(_super)));
}
if (SUPER.length > 0 && SUPER.length <= i) {
i = 0;
}
}
document.body.innerHTML = JSON.stringify(FINAL, null, 4);
输出:
[ { "NAME1": { "12": { "21": 2 } } }, { "NAME1": { "12": { "10": 5 } } }, { "NAME1": { "12": { "11": 2 } } }, { "NAME1": { "12": { "12": 1 } } } ]
有什么新鲜事? (与您的代码相比)
- firstPass 声明为真
- 从 "typeof source[prop] === 'object' && source[prop] !== null && source[prop] ? destination[prop] = clone({}, source[prop]) : (firstPass) ? destination[prop] = number : destination[prop] = number -1;"
处的数字减 1
- 将 firstPass 设置为 false
- 'for' 使用索引 i 而不是让 JS 自己遍历 SUPER(因为我们从 SUPER 中删除了元素)
- 如果我 > SUPER.length
,则将 'i' 重置为零
注意:您可以通过多种不同的方式修复它,这只是其中一种方式;)
ps:尽管代码可以正常工作,但我仍然不知道 "number" 问题的根本原因 =/ 所以,我考虑“(firstPass) ? destination[prop] = number : destination[prop] = number - 1" 是一种解决方法,而不是真正的解决方法。
您可以先生成所有键,查找是否使用该路径插入元素,如果没有则创建一个条目。之后,在对象中构建路径,最后将值添加到最内部对象。
let SUPER5 = [{ "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "11": 1 } } }],
SUPER10 = [{ "NAME1": { "12": { "21": 1 } } }, { "NAME1": { "12": { "21": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "12": 1 } } }, { "NAME1": { "12": { "11": 1 } } }, { "NAME1": { "12": { "11": 1 } } }],
getGrouped = data => {
var r = [],
getKey = o => Object.keys(o)[0];
data.forEach(function (a) {
var o = a,
t = {},
k = getKey(a),
keys = [k],
jointKey;
while (typeof o[k] === 'object') {
o = o[k];
k = getKey(o);
keys.push(k);
}
jointKey = keys.join('|');
if (!this[jointKey]) {
this[jointKey] = t;
r.push(t);
}
keys.pop();
t = keys.reduce((r, a) => r[a] = r[a] || {}, this[jointKey]);
t[k] = (t[k] || 0) + o[k];
}, Object.create(null));
return r;
};
document.write('<pre>' + JSON.stringify(getGrouped(SUPER5), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(getGrouped(SUPER10), 0, 4) + '</pre>');
我有以下代码消除数组中的相等对象,并将最里面的 属性 增加到相等对象的数量:
let SUPER = [{
"NAME1": {
"12": {
"10": 1
}
}
}, {
"NAME1": {
"12": {
"10": 1
}
}
}, {
"NAME1": {
"12": {
"10": 1
}
}
}, {
"NAME1": {
"12": {
"10": 1
}
}
}, {
"NAME1": {
"12": {
"11": 1
}
}
}],
FINAL = [];
for (let _super of SUPER) {
_super = JSON.stringify(_super);
let ii = 1,
ll = SUPER.length,
number = 1;
for (ii; ii < ll; ii++) {
let current = JSON.stringify(SUPER[ii]);
if (_super === current) {
SUPER.splice(ii, 1);
ii--;
number++;
}
}
if (number) {
FINAL.push(function clone(destination, source) {
destination = destination || {};
for (var prop in source) {
typeof source[prop] === 'object' && source[prop] !== null && source[prop] ? destination[prop] = clone({}, source[prop]) : destination[prop] = number;
}
return destination;
}({}, JSON.parse(_super)));
}
}
document.body.innerHTML = JSON.stringify(FINAL, null, 4);
如果没有两个或更多对象时的错误结果,并且几乎可以正常工作。结果应该是:
[{
"NAME1": {
"12": {
"10": 4
}
}
}, {
"NAME1": {
"12": {
"11": 1
}
}
}]
不是:
[{
"NAME1": {
"12": {
"10": 4
}
}
}, {
"NAME1": {
"12": {
"11": 2
}
}
}]
知道为什么吗?
给出的数据是示例数据。我不知道所有对象的实际属性。
问题:
- 它在除第一个迭代之外的所有迭代中都加 1
- 在 SUPER 丢失物品时使用 "for (let _super of SUPER) {"
我测试了更多 'unique' 个元素。如果您 运行 下面的代码,您将看到正确的结果。
var SUPER = [
{ "NAME1": { "12": { "21": 1 } } },
{ "NAME1": { "12": { "21": 1 } } },
{ "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "12": 1 } } },
{ "NAME1": { "12": { "11": 1 } } },
{ "NAME1": { "12": { "11": 1 } } }],
FINAL = [];
var firstPass = true;
for (var i = 0; i < SUPER.length; i++) {
_super = JSON.stringify(SUPER[i]);
let ii = 1,
ll = SUPER.length,
number = 1;
for (ii; ii < ll; ii++) {
let current = JSON.stringify(SUPER[ii]);
if (_super === current) {
SUPER.splice(ii, 1);
ii--;
number++;
}
}
if (number) {
FINAL.push(function clone(destination, source) {
destination = destination || {};
for (var prop in source) {
typeof source[prop] === 'object' && source[prop] !== null && source[prop] ? destination[prop] = clone({}, source[prop]) : (firstPass) ? destination[prop] = number : destination[prop] = number -1;
}
firstPass = false;
return destination;
}({}, JSON.parse(_super)));
}
if (SUPER.length > 0 && SUPER.length <= i) {
i = 0;
}
}
document.body.innerHTML = JSON.stringify(FINAL, null, 4);
输出:
[ { "NAME1": { "12": { "21": 2 } } }, { "NAME1": { "12": { "10": 5 } } }, { "NAME1": { "12": { "11": 2 } } }, { "NAME1": { "12": { "12": 1 } } } ]
有什么新鲜事? (与您的代码相比)
- firstPass 声明为真
- 从 "typeof source[prop] === 'object' && source[prop] !== null && source[prop] ? destination[prop] = clone({}, source[prop]) : (firstPass) ? destination[prop] = number : destination[prop] = number -1;" 处的数字减 1
- 将 firstPass 设置为 false
- 'for' 使用索引 i 而不是让 JS 自己遍历 SUPER(因为我们从 SUPER 中删除了元素)
- 如果我 > SUPER.length ,则将 'i' 重置为零
注意:您可以通过多种不同的方式修复它,这只是其中一种方式;)
ps:尽管代码可以正常工作,但我仍然不知道 "number" 问题的根本原因 =/ 所以,我考虑“(firstPass) ? destination[prop] = number : destination[prop] = number - 1" 是一种解决方法,而不是真正的解决方法。
您可以先生成所有键,查找是否使用该路径插入元素,如果没有则创建一个条目。之后,在对象中构建路径,最后将值添加到最内部对象。
let SUPER5 = [{ "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "11": 1 } } }],
SUPER10 = [{ "NAME1": { "12": { "21": 1 } } }, { "NAME1": { "12": { "21": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "12": 1 } } }, { "NAME1": { "12": { "11": 1 } } }, { "NAME1": { "12": { "11": 1 } } }],
getGrouped = data => {
var r = [],
getKey = o => Object.keys(o)[0];
data.forEach(function (a) {
var o = a,
t = {},
k = getKey(a),
keys = [k],
jointKey;
while (typeof o[k] === 'object') {
o = o[k];
k = getKey(o);
keys.push(k);
}
jointKey = keys.join('|');
if (!this[jointKey]) {
this[jointKey] = t;
r.push(t);
}
keys.pop();
t = keys.reduce((r, a) => r[a] = r[a] || {}, this[jointKey]);
t[k] = (t[k] || 0) + o[k];
}, Object.create(null));
return r;
};
document.write('<pre>' + JSON.stringify(getGrouped(SUPER5), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(getGrouped(SUPER10), 0, 4) + '</pre>');