根据相等对象的数量,消除相等的对象并将最内层属性增加1

时间:2016-05-23 20:07:57

标签: javascript

我有以下代码消除数组中的相等对象,并将最内层属性增加到相等对象的数量:

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
      }
    }
  }]

任何想法为什么?

给出的数据是示例数据。我不知道所有对象的实际属性。

2 个答案:

答案 0 :(得分:1)

您可以先生成所有密钥,如果使用该路径插入元素则查找,如果没有创建条目。之后,在对象中构建路径,最后将值添加到大多数内部对象。

&#13;
&#13;
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>');
&#13;
&#13;
&#13;

答案 1 :(得分:0)

问题:

  • 除了第一个
  • 之外,它在所有迭代中都添加了1
  • 使用“for(super-super SUPER){”当SUPER丢失物品时

我已经测试了更多'独特'元素。如果您运行下面的代码,您将看到正确的结果。

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'&amp;&amp; source [prop]中的数字递减1!== null&amp;&amp; source [prop]?destination [prop] = clone({} ,source [prop]):(firstPass)?destination [prop] = number:destination [prop] = number -1;
  • firstPass 设为false
  • 'for'使用索引i而不是让JS通过自己的方式遍历SUPER(因为我们从SUPER中删除了元素)
  • 如果i&gt;
  • 将'i'重置为零SUPER.length

注意:你可以用许多不同的方式修复它,这只是其中之一;)

ps:尽管代码工作正常,我仍然不知道你的问题的根本原因“number”= /所以,我认为“(firstPass)?destination [prop] = number:destination [prop] =数字 - 1“是一种解决方法而不是真正的解决方法。