简体   繁体   中英

Javascript - sum of JSON Array by using the same date as key

I've 2 JSON arrays and 1 date to indicate the key, how to make it in one line per date basis and sum up the steel and concrete?

var a = ['Nov 1 2016','Nov 2 2016','Nov 3 2016','Nov 4 2016'];
var b = [{Date:'Nov 1 2016', steel:10.98},{Date:'Nov 3 2016', steel:5.67},{Date:'Nov 4 2016', steel:3.14}]
var c = [{Date:'Nov 1 2016', concrete:9.10},{Date:'Nov 2 2016', concrete:16.8},{Date:'Nov 4 2016', concrete:7.20}]

//output sum of steel and concrete
var x  =  [{Date:'Nov 1 2016', val:20.08},{Date:'Nov 2 2016', val:16.8},{Date:'Nov 3 2016', val:5.67},{Date:'Nov 4 2016', val:10.34}]

What you can do is iterate over the dates array and for every date find the corresponding item in b and c (if not found provide a default item with a 0 value), and sum up their respective steel and concrete properties.

In other words, convert ( map ) every date string into an object containing that date and the sum of steel and concrete for that date:

// dates is the `a` array, steelDays is the `b` array, concreteDays is the `c` array
const result = dates.map(date =>
  toDateAndValueObj(
    date,
    sumSteelAndConcrete(
      findByDate(steelDays, date),   
      findByDate(concreteDays, date) 
    )
  )
);

Where the functions would be

// converts a date and a value into an object containing that date and that value
const toDateAndValueObj = (date, val) => ({ date, val });

// takes two objects (or the objects with default values if passed undefined) and sums up their respective `steel` and `concrete` properties
const sumSteelAndConcrete = (s = { steel: 0 }, c = { concrete: 0 }) => s.steel + c.concrete;

// finds an item in the array who's Date property lexicographically equals the given date string
const findByDate = (arr, date) => arr.find(item => item.Date === date);

Note that I'm using string comparison for dates here for simplicity purposes. If you're using actual dates, you might need to construct Date objects and use getTime to compare them:

const findByDate = (arr, date) => arr.find(item => new Date(item.Date).getTime() === new Date(date).getTime());

Full demo:

 const dates = ['Nov 1 2016','Nov 2 2016','Nov 3 2016','Nov 4 2016']; const steelDays = [{Date:'Nov 1 2016', steel:10.98},{Date:'Nov 3 2016', steel:5.67},{Date:'Nov 4 2016', steel:3.14}]; const concreteDays = [{Date:'Nov 1 2016', concrete:9.10},{Date:'Nov 2 2016', concrete:16.8},{Date:'Nov 4 2016', concrete:7.20}]; const toDateAndValueObj = (date, val) => ({ date, val }); const sumSteelAndConcrete = (s = { steel: 0 }, c = { concrete: 0 }) => s.steel + c.concrete; const findByDate = (arr, date) => arr.find(item => item.Date === date); const result = dates.map(date => toDateAndValueObj( date, sumSteelAndConcrete( findByDate(steelDays, date), findByDate(concreteDays, date) ) ) ); console.log(result); 

 var b = [{Date:'Nov 1 2016', steel:'10.98'},{Date:'Nov 3 2016', steel:'5.67'},{Date:'Nov 4 2016', steel:'3.14'}]; var c = [{Date:'Nov 1 2016', concrete:'9.10'},{Date:'Nov 2 2016', concrete:'16.8'},{Date:'Nov 4 2016', concrete:'7.20'}]; var obj = {}; for(var index in b){ obj[b[index]['Date']] = b[index]['steel']; } for(index in c){ if(obj.hasOwnProperty(c[index]['Date'])){ obj[c[index]['Date']] += c[index]['concrete']; }else{ obj[c[index]['Date']] = c[index]['concrete']; } } var result = []; for(var key in obj){ result.push({Date:key, val:obj[key]}); } console.log(result); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM