【问题标题】:How to reduce an array of objects and avoid to overwrite string properties values and just sum integers values?如何减少对象数组并避免覆盖字符串属性值而仅对整数值求和?
【发布时间】:2016-06-21 09:49:07
【问题描述】:

我有一个按不同类别分组的数组,每个类别都嵌套了更多具有不同值(数字和字符串)的对象,我必须减少这些对象(字符串除外)。 Reduce 可以很好地处理对它们求和的数值,但它会覆盖字符串值,只保留最后一个。

我正在尝试按类别减少对象/字典,并用每个类别的单位总和填充表格,但如果子类别和名称不同,则不要将它们相加。

这是一个演示:

var data = {
  'Category xxxx': [
    {
      units: 1234,
      subcategory: 'wolves',
      name: 'Starks'
    },
    {
      units: 1345354,
      subcategory: 'wolves',
      name: 'Starks'
    },
   {
      units: 666,
      subcategory: 'dragons',
      name: 'Targaryens'
    }
  ], 
  'Category yyyy': [
    {
      units: 7783,
      subcategory: 'lions',
      name: 'Lanisters'
    },
    {
      units: 1267878,
      subcategory: 'spires',
      name: 'Martells'
    }
  ]
}

var test = _.map(data, function (value, key) {
  var returnedData = {
    Category: key,
    units: _(value).reduce(function (memo, metrics) {
      return memo + metrics.units;
    }, 0),
    subcategory: _(value).reduce(function (memo, metrics) {
      return metrics.subcategory;
    }, 0),
    name: _(value).reduce(function (memo, metrics) {
      return metrics.name;
    }, 0),
  };
  return returnedData;
});

console.log(test)
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

单位(整数)加起来很好,但字符串被最后一次迭代的字符串属性覆盖。

我想获得这样的东西,如果字符串不同,则整数不会相加。

returnedData = {
  'Category xxxx': [
    {
      units: 1346588,
      chivalry: 'wolves',
      name: 'Starks'
    },
    {
      units: 666,
      subcategory: 'dragons',
      name: 'Targaryens'
    }
  ], 
  'Category yyyy': [
    {
      clicks: 7783,
      subcategory: 'lions',
      name: 'Lanisters'
    },
    {
      clicks: 1267878,
      subcategory: 'spires',
      name: 'Martells'
    }
  ]
}

最好的方法是什么?

【问题讨论】:

  • 看起来很简单$.each
  • @Justinas:没有jquery 标签,即使有,$.each 也是 so 2008 年。:-) Array#forEach 或者可能是 Array#reduce适用。
  • @phileras 你能提供一个预期结果的例子以及你尝试了什么吗?
  • 是的@Justinas 我正在尝试使用reduce,在这种情况下下划线reduce,但如果可能的话我会使用javascript array.reduce。
  • 嗨 @T.J.Crowder 我想要类似于 Nina 答案的结果,我在这里展示的数组是一个演示,在这种情况下数据非常大,我将不得不做更多的子组,但想法和结果尼娜被挪用了。之后我需要检查性能,但这是一个乞求。谢谢:)

标签: javascript arrays json


【解决方案1】:

最后,这个提案使用一个对象作为对result对象的引用。

如果没有可用的result 对象,则它会创建一个具有所需类别的新对象。对于子类别,它会生成一个元素,并将其推送到结果数组。

使用hash 维护计数作为对result 元素的引用。

var data = { 'Category xxxx': [{ clicks: 1234, subcategory: 'dogs', name: 'jhon doe' }, { clicks: 1345354, subcategory: 'dogs', name: 'jhon doe' }], 'Category yyyy': [{ clicks: 7783, subcategory: 'frogs', name: 'lanisters' }, { clicks: 1267878, subcategory: 'rats', name: 'perry' }] },
    result = {};

Object.keys(data).forEach(function (k) {
    var hash = Object.create(null);
    if (!result[k]) {
        result[k] = [];
    }
    data[k].forEach(function (a) {
        if (!hash[a.subcategory]) {
            hash[a.subcategory] = { clicks: 0, subcategory: a.subcategory, name: a.name };
            result[k].push(hash[a.subcategory]);
        }
        hash[a.subcategory].clicks += a.clicks;
    });
});

console.log(result);

【讨论】:

  • 不错,尼娜!虽然 FWIW 我会避免使用 this 作为类别子类别的映射的(感知的)复杂性,但大概我们只需要在整个类别中组合 within 条目。当你自己做的时候,只是修改你的原始解决方案,着眼于在上面编辑它(毕竟你已经完成了大部分工作)。 FWIW,原来是这样:pastie.org/10885155
  • @T.J.Crowder,你是对的,不需要类别,只需要子。你的解决方案模仿原来的。
  • 我建议提出一个新问题。 cmets 不适合它。
  • @mortezaT,也许你更容易看起来像我的这个answer。在arr2 中有一个名为'toString' 的属性。您可以使用{} 而不是Object.reate(null) 执行相同的操作。你明白了。
  • @phileras,所以出乎意料,不可能说出你的问题在哪里。作为一个新问题,你可能更容易用 dynamic 变量突出你的特殊问题(这是一种重言式......?)。
【解决方案2】:

我认为这也可能是答案。

var data = {
	'Category xxxx': [
	{ units: 1234, subcategory: 'wolves', name: 'Starks' }, 
	{ units: 1345354, subcategory: 'wolves', name: 'Starks' }, 
	{ units: 666, subcategory: 'dragons', name: 'Targaryens' }
	],
	'Category yyyy': [
	{ units: 7783, subcategory: 'lions', name: 'Lanisters' }, 
	{ units: 1267878, subcategory: 'spires', name: 'Martells' }
	]
};

var result = {};

Object.keys(data).forEach(function (key) {
	var hash = {};
	data[key].forEach(function (v, k) {
		isNaN(hash[(k = v.subcategory + v.name)]) ?
			(hash[k] = this.push(v) - 1) :
			(this[hash[k]].units += v.units);
	}, (this[key] = []));
}, result);

console.log(result)

【讨论】:

  • 感谢您的回答@mortezaT 它也很好用,现在我正在寻找并比较两个答案以获得最佳性能。我也在考虑识别 typeoff 数据属性以尽可能创建最通用的函数,因为它将管理非常不同类型的数据。 ;)
  • @phileras 这可以管理一些条款,但正如 Nina 在评论中提到的那样,您应该提出一个新问题并完整描述您的条款。
  • 新问题已发送@mortezaT。抱歉,如果这个问题看起来不是很具体,但是我使用 JS OO 的技术语言不是很好,因为我是自学成才并且更专注于视觉内容,所以我缺乏与之相关的技术语言
  • @phileras 你能给我新问题的链接吗?我也是JS OO中的自我思考者。
  • 抱歉@mortezaT 问题已被删除,因为他们将其标记为重复,所以我正在阅读和搜索内容以尝试自己制作,非常感谢您的帮助! :)
猜你喜欢
  • 2018-04-15
  • 1970-01-01
  • 2019-05-18
  • 2021-10-25
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
  • 1970-01-01
  • 2017-11-27
相关资源
最近更新 更多