合并数组与共享元素保持其他属性

时间:2017-12-13 19:35:28

标签: javascript

我有一个这样的数组:

  arr = [
         [ Date1, 1, null],
         [ Date1, null, 2],
         [ Date2, 1, null],
         [ Date2, null, 2],
         [ Date3, 1, null],
         [ Date3, null, 2],
         [ Date4, 2, null],
         [ Date5, 1, null] ];

它永远不会同时具有空值但在日期上只能有1个值,预期为:

    arr = [
    [ Date1, 1, 2],
    [ Date2, 1, 2],
    [ Date3, 1, 2],
    [ Date4, 2, null],
    [ Date5, 1, null] ];

2 个答案:

答案 0 :(得分:2)

您可以使用reduce执行此操作。只需检查您是否已经有一个具有相同第一个元素的项目,如果是,请将它们合并:

const arr = [
  [ "Date1", 1, null],
  [ "Date1", null, 2],
  [ "Date2", 1, null],
  [ "Date2", null, 2],
  [ "Date3", 1, null],
  [ "Date3", null, 2],
  [ "Date4", 2, null],
  [ "Date5", 1, null],
];

const result = arr.reduce((combined, item) => {
  // Do we already have an item with the same first element?:
  const existingItem = combined.find(x => x[0] === item[0]);
  
  if (!existingItem) {
    // If not, just add the current item to the array
    combined.push(item);
  } else {
    // If so, go through the current item, and add any non-null elements to the existing item.
    item.forEach((element, index) => {
      if (element) existingItem[index] = element;
    });
  }
  return combined;
}, []);

console.log(result)

编辑:一些警告:

在你的代码片段中,我不确定你的日期对象的类型是什么。重要的是它们可以与===进行比较。如果不能,则必须将find中的函数替换为可以正确检查这些日期的任何类型的相等的函数。

其次,替换现有项目(在forEach块中)中的元素是基于简单的真值检查。但是,如果您的某些商品有效但却有误(例如,数字0),则您需要将代码if (element) ...替换为if (element !== null) ...,以便它会允许虚假但有效的值。

基本上,以您需要的任何方式修改它以适合您的用例,只需知道此代码正在做什么以及可能不合适的地方。

答案 1 :(得分:1)

编辑:我认为CRices答案更好,更优雅。

我不确定我是否理解,但这样的事情会起作用。

也许一些Array.reduce调用也可以工作......

var merged = [];

arr.forEach(function(value){
    var date = value[0];
    if (typeof date.extra1 === "undefined" || value[1] !== null) {
        date.extra1 = value[1];
    }
    if (typeof date.extra2 === "undefined" || value[2] !== null) {
        date.extra2 = value[2];
    }
    if (merged.indexOf(date) === -1) {
        mered.push(date);
    }
});

merged = merged.map(function(value){
    return [
        value,
        value.extra1,
        value.extra2
    ]
});