【问题标题】:Javascript - Reduce array with multiple-key objects [duplicate]Javascript - 使用多键对象减少数组[重复]
【发布时间】:2016-12-01 05:13:26
【问题描述】:

我想修改一个 Javascript 数组,以便指定属性具有相同值的元素合并到一个对象中,而其他属性则保存为逗号分隔的字符串、JSON 字符串或数组。基本上,我想转这个:

[
    {
        "language" : "english",
        "type" : "a",
        "value" : "value1"
    },
    {
        "language" : "english",
        "type" : "a",
        "value" : "value2"
    },
    {
        "language" : "english",
        "type" : "b",
        "value" : "value3"
    },  
    {
        "language" : "spanish",
        "type" : "a",
        "value" : "valor1"
    }
]

进入这个:

[
    {
        "language" : "english",
        "type" : "a",
        "value" : ["value1" , "value2"]  // A Json string is welcome too
    },
    {
        "language" : "english",
        "type" : "b",
        "value" : "value3"
    },  
    {
        "language" : "spanish",
        "type" : "a",
        "value" : "valor1"
    }
]

我尝试过迭代和过滤,然后按照 sn-p.但我想知道是否有更优雅的方式来做到这一点。

也欢迎 P.S EcmaScript6 和其他 JS 库建议。

var originalArray = [
	{
		"language" : "english",
		"type" : "a",
		"value" : "value1"
	},
	{
		"language" : "english",
		"type" : "a",
		"value" : "value2"
	},
	{
		"language" : "english",
		"type" : "b",
		"value" : "value3"
	},	
	{
		"language" : "spanish",
		"type" : "a",
		"value" : "valor1"
	}
];

var resultingArray = [];

// iterate through the original array
$.each(originalArray, function(i, val) {
  // apply filter on key properties (i.e. language and type)
  var result = resultingArray.filter(function( obj ) {
    return (obj.language === val.language && obj.type === val.type);
  });
  // if a record exists, update its value
  if (result.length === 1) {  
    result[0].value += (", " + val.value);
  } 
  // else, add value
  else if (result.length === 0) {
    resultingArray.push(val);
  }
  // if multiple rows exist with same key property values...
  else {
    alert("Too many records with language '" + val.language + "' and type '" + val.type + "'");
  }
});

console.log(JSON.stringify(resultingArray));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

【问题讨论】:

  • Here was my suggested solution,取决于你认为什么“优雅”。您的代码的问题在于它在O(N^2) 中运行,因为filter 函数在each 的第一次迭代中运行一次,在第二次迭代中运行两次,依此类推。没必要这么做。
  • here 是我的,而value 始终是一个数组。顺便说一句:我认为您的alert() 声明永远不会被触发。如果您不想为同一个键(语言 + 类型)提供两次相同的 ,则必须采用不同的方式。
  • 你好,你的JS用的是jQuery,为什么不加jQuery标签?我正在学习并确保使用纯 JavaScript forEach 来帮助您 -_-!
  • 顺便说一句,我不确定它是否可以看到 the suggested questionexact 副本,因为 OP 正在使用 composite key,使得现有的答案不充分。
  • @Arnauld 我不确定添加辅助检查是否需要一个全新的问题。给出的答案是完全合适的,只需要稍作修改。

标签: javascript ecmascript-6


【解决方案1】:

这是你需要的吗?

var baseData= [
    {
        "language"  : "english",
        "type" : "a",
        "value" : "value1"
    },
    {
        "language" : "english",
        "type" : "a",
        "value" : "value2"
    },
    {
        "language" : "english",
        "type" : "b",
        "value" : "value3"
    },  
    {
        "language" : "spanish",
        "type" : "a",
        "value" : "valor1"
    }
];

var newData = [];
baseData.forEach(function(item, index) {
  if (newData.length === 0) {
    newData.push(item);
    
  } else {
    var dIndex = -1;
    newData.forEach(function(itm, idx) {
      if (item.language === itm.language && item.type === itm.type) dIndex = idx;
    });
    
    if (dIndex !== -1) {
      var oldValue = newData[dIndex].value;
      
      if (typeof(oldValue).toString() === 'string') {
        newData[dIndex].value = [oldValue, item.value];
      }
    } else {
      newData.push(item);
    }
  }
});
console.log(newData);

【讨论】:

    猜你喜欢
    • 2019-01-26
    • 2021-04-02
    • 2019-07-20
    • 1970-01-01
    • 2021-01-15
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多