首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归重建对象,如果已经存在,则获取最内部的属性,并逐个增加数目。

递归重建对象,如果已经存在,则获取最内部的属性,并逐个增加数目。
EN

Stack Overflow用户
提问于 2016-05-23 23:25:29
回答 1查看 108关注 0票数 0

我有以下代码:

代码语言:javascript
复制
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作用域,我被搜索过,但没有找到任何东西。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-24 07:38:12

改写后的版本,供下文讨论。

代码语言:javascript
复制
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.reduceArray.prototype.forEach都为数组中的每个元素调用一个函数,但我发现在遍历keys数组时使用reduce修改了另一个数组对象的结构,并使用变量名的更改将其与forEach交换掉。

算法保持不变,我希望你现在能看到它的工作原理。我认为原始代码很难维护。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37402081

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档