合并新对象中的对象属性,并在没有jquery和lodash的情况下推入数组

时间:2017-01-18 11:59:23

标签: javascript arrays data-structures

我有一系列具有相同属性的对象。如何将具有相同period属性的对象合并到新的对象数组中。我在stackoverflow中看到了这些示例,但它们主要使用外部库,如JQuery或lodash。我可以在vanilla.js中制作这个吗?

Here 是Plunkr,带有代码和预期值的标记。谢谢你的帮助

5 个答案:

答案 0 :(得分:0)

您可以使用forEach()循环并添加到新阵列。



var a = [{"period":"01.07.2016","count":11,"scale":"d"},{"period":"01.07.2016","count":22,"scale":"n"},{"period":"01.08.2016","count":33,"scale":"n"},{"period":"01.08.2016","count":44,"scale":"d"},{"period":"01.09.2016","count":55,"scale":"d"},{"period":"01.09.2016","count":66,"scale":"n"}]

var result = []
a.forEach(function(e) {
  if (!this[e.period]) {
    this[e.period] = {
      date: e.period.split('.')[1],
      day: 0,
      night: 0
    }
    result.push(this[e.period])
  }
  if (e.scale == 'd') {
    this[e.period].day = (this[e.period].day || 0) + e.count
  } else if (e.scale == 'n') {
    this[e.period].night = (this[e.period].night || 0) + e.count
  }
}, {})

console.log(result)




答案 1 :(得分:0)

您可以将其与日期分组,并使用对象作为哈希表的引用。另一个对象用于访问day / nicht属性。



var array = [{ period: '01.07.2016', count: 11, scale: 'd' }, { period: '01.07.2016', count: 22, scale: 'n' }, { period: '01.08.2016', count: 33, scale: 'n' }, { period: '01.08.2016', count: 44, scale: 'd' }, { period: '01.09.2016', count: 55, scale: 'd' }, { period: '01.09.2016', count: 66, scale: 'n' }],
    grouped = [];

array.forEach(function (a) {
    var day = a.period.slice(3, 5);
    if (!this[day]) {
        this[day] = { date: day, day: 0, night: 0 };
        grouped.push(this[day]);
    }
    this[day][{ d: 'day', n: 'night' }[a.scale]] += a.count;
}, Object.create(null));

console.log(grouped);

.as-console-wrapper { max-height: 100% !important; top: 0; }




您也可以在哈希表上使用闭包,而不使用thisArg



var array = [{ period: '01.07.2016', count: 11, scale: 'd' }, { period: '01.07.2016', count: 22, scale: 'n' }, { period: '01.08.2016', count: 33, scale: 'n' }, { period: '01.08.2016', count: 44, scale: 'd' }, { period: '01.09.2016', count: 55, scale: 'd' }, { period: '01.09.2016', count: 66, scale: 'n' }],
    grouped = [];

array.forEach(function (hash) {
    return function (a) {
        var day = a.period.slice(3, 5);
        if (!hash[day]) {
            hash[day] = { date: day, day: 0, night: 0 };
            grouped.push(hash[day]);
        }
        hash[day][{ d: 'day', n: 'night' }[a.scale]] += a.count;
    };
}(Object.create(null)));

console.log(grouped);

.as-console-wrapper { max-height: 100% !important; top: 0; }




在不滥用thisArg和IFFE

的情况下清理版本



var array = [{ period: '01.07.2016', count: 11, scale: 'd' }, { period: '01.07.2016', count: 22, scale: 'n' }, { period: '01.08.2016', count: 33, scale: 'n' }, { period: '01.08.2016', count: 44, scale: 'd' }, { period: '01.09.2016', count: 55, scale: 'd' }, { period: '01.09.2016', count: 66, scale: 'n' }],
    grouped = function () {
        var result = [],
            hash = Object.create(null);

        array.forEach(function (a) {
            var day = a.period.slice(3, 5);
            if (!hash[day]) {
                hash[day] = { date: day, day: 0, night: 0 };
                result.push(hash[day]);
            }
            hash[day][{ d: 'day', n: 'night' }[a.scale]] += a.count;
        });
        return result;
    }();

console.log(grouped);

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 2 :(得分:0)

您可以使用 forEach 循环遍历数组,然后使用 some 来检查是否已存在具有相同键的对象来合并对象。

P.S:您预期的输出有一段错误:“01.08.2016”。它已经改变了白天和黑夜的数量。

var a = [{
  'period': "01.07.2016",
  'count': 11,
  'scale': 'd'
}, {
  'period': "01.07.2016",
  'count': 22,
  'scale': 'n'
}, {
  'period': "01.08.2016",
  'count': 33,
  'scale': 'n'
}, {
  'period': "01.08.2016",
  'count': 44,
  'scale': 'd'
}, {
  'period': "01.09.2016",
  'count': 55,
  'scale': 'd'
}, {
  'period': "01.09.2016",
  'count': 66,
  'scale': 'n'
}]


function createMatrix(list) {
  var arr = [];
  list.forEach((item) => {
    var key = item["period"];
    var result = arr.some(function(currentValue, index, arr) {
      if (arr[index].date == key.split(".")[1]) {
        var dayNight = (item.scale == "d" ? "day" : "night");
        arr[index][dayNight] = item.count;
        return true;
      }
    });

    if (result === false) {
      var dayNight = (item.scale == "d" ? "day" : "night");
      var obj = {};
      obj[dayNight] = item.count;
      obj["date"] = key.split(".")[1];
      arr.push(obj);
    }

  });
  return arr;
}

console.log(createMatrix(a));

答案 3 :(得分:0)

首先,我们可以通过“scale”对原始数据列表进行排序,然后在一个reduce内获取收集的目标/期望列表...例如.e.g。 ...



var rawData = [{
  'period': '01.07.2016',
  'count': 11,
  'scale': 'd'
}, {
  'period': '01.07.2016',
  'count': 22,
  'scale': 'n'
}, {
  'period': '01.08.2016',
  'count': 33,
  'scale': 'n'
}, {
  'period': '01.08.2016',
  'count': 44,
  'scale': 'd'
}, {
  'period': '01.09.2016',
  'count': 55,
  'scale': 'd'
}, {
  'period': '01.09.2016',
  'count': 66,
  'scale': 'n'
}];


// expecting
/*
  result = [{
    date  : '07',
    day   : 11,
    night : 22
  }, {
    date  : '08',
    day   : 44,
    night : 33
  }, {
    date  : '09',
    day   : 55,
    night : 66
  }]
*/


function sortByDay(a, b) {
  return ((a.scale < b.scale) ? -1 : ((a.scale > b.scale) ? 1 : 0));
}

function collectSortedDayAndNightTotals(collector, item/*, idx, list*/) {
  var
    dateRegistry    = collector.dateRegistry,
    dateKey         = item.period,
    registeredItem  = dateRegistry[dateKey];

  if (registeredItem == null) {
    dateRegistry[dateKey] = item;
  } else {
    collector.totalList.push({
      date  : dateKey.split('.')[1],
      day   : registeredItem.count,
      night : item.count
    });
  }
  return collector;
}


var result = rawData.sort(sortByDay).reduce(collectSortedDayAndNightTotals, {

  dateRegistry: {},
  totalList   : []

}).totalList;


console.log('result : ', result);
&#13;
&#13;
&#13;

答案 4 :(得分:0)

我用reduce

var arr = [{
  'period': '01.07.2016',
  'count': 11,
  'scale': 'd'
},
{
  'period': '01.07.2016',
  'count': 22,
  'scale': 'n'
},
{
  'period': '01.07.2016',
  'count': 22,
  'scale': 'n'
},
{
  'period': '01.08.2016',
  'count': 11,
  'scale': 'd'
},
{
  'period': '01.08.2016',
  'count': 22,
  'scale': 'n'
},
{
  'period': '01.08.2016',
  'count': 22,
  'scale': 'n'
},
];


function functionName(a) {
  var b = [];
  var c = 0;

  var d = a.reduce(function(first, second, i){
    if(first.period == second.period){
        b[c] = b[c] || [{
        day: '',
        night: '',
        date: '',
      }];
      if (first.scale == 'd') {
        b[c].day = b[c].day + first.count || first.count;
      }else {
        b[c].night = b[c].day + first.count || first.count
      }
      b[c].date = b[c].date  || first.period;
    }else {
      c= c + 1;
    }
    return second;
  });
  b[c] = b[c] || [{
    day: '',
    night: '',
    date: '',
  }];
  if (d.scale == 'd') {
    b[c].day = b[c].day + d.count || d.count;
  }else {
    b[c].night = b[c].day + d.count || d.count;
  }
  b[c].date = b[c].date  || d.period;
  return b;

}

console.log(functionName(arr));