我有以下代码:
let SUPER = [{ "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "11": 1 } } }], FINAL = [];
SUPER.forEach(function(object) {
var key = object => Object.keys(object)[0]; // pega key número um
var self = {}; // {}
var oneKey = key(object); // 'NAME'
var keys = [oneKey]; // [ 'NAME' ]
var jointKey; // undefined
while (typeof object[oneKey] === 'object') {
object = object[oneKey]; // { '1': 1 }
oneKey = key(object); // 1
keys.push(oneKey); // keys: [ 'NAME', '1' ]
}
jointKey = keys.join('|'); // jointKey NAME|1
if (!this[jointKey]) {
this[jointKey] = self;
FINAL.push(self);
}
// console.log(self)
keys.pop(); // keys: [ 'NAME' ]
self = keys.reduce((previousValue, currentValue) => {
return previousValue[currentValue] = previousValue[currentValue] || {};
}, this[jointKey] /* { NAME: {} } */ );
self[oneKey] = (self[oneKey] || 0) + object[oneKey];
}, Object.create(null));
document.body.innerHTML = JSON.stringify(FINAL, 0, 4);
它消除了具有相同属性的对象,得到了其余对象的最内部属性,并随着过去相等对象的数量的增加而增加。快跑,你会看到的。
我绞尽脑汁想弄明白这是怎么回事。谁能给我一个很好的解释?
在第二个迭代中,对象的值不是数组Super中的第二个值,这怎么可能?
另一个谜团是这个Object.create(null),它正在改变forEach作用域,我被搜索过,但没有找到任何东西。
发布于 2016-05-24 07:38:12
改写后的版本,供下文讨论。
let SUPER =
[ { "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "10": 1 } } }, { "NAME1": { "12": { "10": 1 } } },
{ "NAME1": { "12": { "11": 1 } } }
];
let FINAL = [];
SUPER.forEach(function(object) {
var firstKey = (obj) => Object.keys(obj)[0]; // first enumerable ownProperty key of an object
var key; // object property value
var leafObj; // the last object in a chain of first property object values
var leafKey; // the first key in leafObj
var keys = []; // array of keys returned by firstKey;
var keyList; // "|" separated list of first keys
// Create keys array while finding leafKey and leafObj
for( var o = object;;)
{ key = firstKey(o);
keys.push(key);
if( typeof o[ key] != "object")
break;
o = o[ key];
}
leafObj = o;
leafKey = key;
keyList = keys.join('|'); // create keyList
// initialize this[keylist] to empty array and push/copy to FINAL as required
if (!this[keyList])
{
FINAL.push(
this[keyList] = {}
);
}
keys.pop(); // remove leafKey from keys array;
// add empty arrays to a branch of keyList bush as required
var child = this[keyList];
keys.forEach( function( key)
{ child = child[key] || (child[ key] = {});
});
child[leafKey] = (child[leafKey] || 0) + leafObj[leafKey];
}, Object.create(null));
document.write( JSON.stringify(FINAL, 0, 4)); // for script in head section基本上,我是以维护程序员的身份接触代码的,他不知道代码是做什么的,也不知道它是如何工作的。从第一次读到,两者都不是不言自明的。
第一个while循环及其前面的初始化器的结构重写是决定变量用于什么并给它们命名的一部分。特别是,我发现使用"self“作为变量名的选择具有误导性。通常,self变量用于将this的值传递给构造函数中的嵌套函数。使用它作为空数组的名称并不是无效的,但是没有向这个读者传达任何目的感。更糟糕的是,self后来被重新分配用于无关的用途。
虽然Array.prototype.reduce和Array.prototype.forEach都为数组中的每个元素调用一个函数,但我发现在遍历keys数组时使用reduce修改了另一个数组对象的结构,并使用变量名的更改将其与forEach交换掉。
算法保持不变,我希望你现在能看到它的工作原理。我认为原始代码很难维护。
https://stackoverflow.com/questions/37402081
复制相似问题