将数组中的对象与相同的键组合在一起(日期)

时间:2017-08-18 00:04:15

标签: javascript arrays sorting for-loop ecmascript-6

我有一个对象数组,我想组合具有相同日期值的对象,所以我有一个像这样的数组。我正在使用.map(i =>)循环遍历它们并对前一个索引进行取消,但我得到了错误的值。

 [{ id: '8',
   name: 'hfh',
   consumed_date: '2017-03-14',
   calories: 8952 },
 { id: '7',
   name: 'onion',
   consumed_date: '2017-03-14',
   calories: 224},
 { id: '6',
   name: 'onion',
   consumed_date: '2017-03-14',
   calories: 279},
 { id: '2',
   name: 'Ready-to-Serve Chocolate Drink',
   consumed_date: '2017-01-01',
   calories: 3036} ]

我想最终得到像

这样的数组
[{date: 2017-03-14,
calories: 9455},
date: 2017-01-01,
calories: 3036}]

7 个答案:

答案 0 :(得分:1)

Reduce非常适合这样的情况:我们需要“循环”所有项目,但我们不希望直接的“a => modify(a)” - 就像{{{} 1}},但需要将几个值减少或折叠成其他值(在这种情况下,输入和输出都是一个数组,但有些值只减少到一个)。

我们需要一些变量来保持状态(到目前为止的进度),同时我们遍历所有项目。更强制性的风格可以通过在for循环之外声明的变量来解决,但是在map中“进展到目前为止” - 变量(reduce)在每次迭代中传递,下一个项目。

acc

(此解决方案假定数据按日期排序。)

答案 1 :(得分:0)

可能是这样的:

Object.values(arr.reduce(function(obj, entry){
    if(!(entry.consumed_date in obj)){
        obj[entry.consumed_date] = {
            date: entry.consumed_date,
            calories: 0
        };
    }
    obj[entry.consumed_date].calories += entry.calories;

    return obj;
}, {}));

https://jsfiddle.net/DerekL/9gyL9dfs/

答案 2 :(得分:0)

这大量使用ES 6功能,如箭头函数,参数解构,Object.entries,对象速记属性等。确保转换。

Object.entries(arr.reduce((acc, record) => {
  if (!acc[record.consumed_date]) acc[record.consumed_date] = 0;
  acc[record.consumed_date] += record.calories;
  return acc;
}, {})).map(([date, calories]) => {date, calories});

答案 3 :(得分:0)

let array =  [{ id: '8',
    name: 'hfh',
    consumed_date: '2017-03-14',
    calories: 8952 },
    { id: '7',
        name: 'onion',
        consumed_date: '2017-03-14',
        calories: 224},
    { id: '6',
        name: 'onion',
        consumed_date: '2017-03-14',
        calories: 279},
    { id: '2',
        name: 'Ready-to-Serve Chocolate Drink',
        consumed_date: '2017-01-01',
        calories: 3036} ]

let newArray = array.reduce((sum, value)=>{
    if(value.consumed_date === '2017-03-14') {
        return sum.concat(value)
    }else{
        return sum
    }
}, []);

console.log(newArray);

答案 4 :(得分:0)

var after = {},
    found;

for (var i = 0; i < arr.length; i++) {
  found = false;
  for (var j = 0; j < after.length; j++) {
    if (arr[i]['consumed_date'] == after[j]['date']) {
      after[j]['calories'] += arr[i]['calories'];
      found = true;
      break;
    }
  }
  if (!found) {
    after[after.length] = {
      'date': arr[i]['consumed_date'],
      'calories': arr[i]['calories']
    }
  }
}

将较大的数组(包含每日条目)命名为arr,或在整个代码中更改arr。然后,这些值将根据请求分配给after

注意 在这里相当糟糕的例子,也没有经过测试,但我已经尽力了:/

答案 5 :(得分:0)

首先,使用consume_date作为索引来减少数据,并且整个事物将通过Object.entries转换为数组并映射结果。

var json = [{ id: '8',
   name: 'hfh',
   consumed_date: '2017-03-14',
   calories: 8952 },
 { id: '7',
   name: 'onion',
   consumed_date: '2017-03-14',
   calories: 224},
 { id: '6',
   name: 'onion',
   consumed_date: '2017-03-14',
   calories: 279},
 { id: '2',
   name: 'Ready-to-Serve Chocolate Drink',
   consumed_date: '2017-01-01',
   calories: 3036} ];
   
  var newar = json.reduce((acc, val) => {
    if(acc[val.consumed_date] === undefined) {
      acc[val.consumed_date] = { date: val.consumed_date, calories: val.calories };
    }
    else {
      acc[val.consumed_date].calories = acc[val.consumed_date].calories + val.calories;
    }

    return acc;
   }, []);
   
   document.getElementById("content").innerHTML = JSON.stringify(Object.entries(newar).map((e) => e[1]));
<pre id="content"></pre>

答案 6 :(得分:0)

对于数组中的每个项目,请检查我们是否已经看过它。如果有的话加入卡路里。如果没有将新项目添加到组合列表中。

如果你可以使用Lodash:

file:///var/mobile/Containers/Data/Application/.../image.jpg

或者你可以自己做这样的事情:

- (NSURL *)moveFileToTemporaryMemory:(NSURL *)url {
  NSError *readingError, *writingError;
  NSString *fileName = url.lastPathComponent;
  NSURL *tempURL = [[NSURL fileURLWithPath:NSTemporaryDirectory()] URLByAppendingPathComponent:fileName];
  NSData *data = [NSData dataWithContentsOfURL:url options:NSDataReadingMappedIfSafe error:&readingError];
  [data writeToURL:tempURL options:NSDataWritingAtomic error:&writingError];
  return tempURL;
}