Как получить сумму значений в массиве объектов javascript - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть следующий массив:

[
{genderAge: "Male 25-39", count: 13029, weightedCount: 18475.6824262314, matchingSegment: 2},
{genderAge: "Female 55+", count: 35639, weightedCount: 32294.5926147014, matchingSegment: 8},
{genderAge: "Female 25-39", count: 23285, weightedCount: 20645.0599977815, matchingSegment: 6},
{genderAge: "Female 18-24", count: 7745, weightedCount: 8497.30029399032, matchingSegment: 5},
{genderAge: "Male 55+", count: 38018, weightedCount: 28589.2793936886, matchingSegment: 4},
{genderAge: "Male 18-24", count: 4038, weightedCount: 8122.65161312996, matchingSegment: 1},
{genderAge: "Female 40-54", count: 23051, weightedCount: 22834.3167597392, matchingSegment: 7},
{genderAge: "Male 40-54", count: 17278, weightedCount: 19681.8852663563, matchingSegment: 3}
]

Я хочу преобразовать этот массив объектов в массив с двумя объектами, содержащими суммированные данные (count, weightedCount и MatchSegment) для мужчин и женщин.Есть ли краткий способ добиться этого с помощью Lodash и / или ES6?

обновление: извинения Я предоставил неверные данные.

Ответы [ 7 ]

0 голосов
/ 28 сентября 2018

Вы можете использовать метод уменьшения

var list = [
{genderAge: "Male 25-39", count: 13029, weightedCount: 18475.6824262314, matchingSegment: 2},
{genderAge: "Female 55+", count: 35639, weightedCount: 32294.5926147014, matchingSegment: 8},
{genderAge: "Female 25-39", count: 23285, weightedCount: 20645.0599977815, matchingSegment: 6},
{genderAge: "Female 18-24", count: 7745, weightedCount: 8497.30029399032, matchingSegment: 5},
{genderAge: "Male 55+", count: 38018, weightedCount: 28589.2793936886, matchingSegment: 4},
{genderAge: "Male 18-24", count: 4038, weightedCount: 8122.65161312996, matchingSegment: 1},
{genderAge: "Female 40-54", count: 23051, weightedCount: 22834.3167597392, matchingSegment: 7},
{genderAge: "Male 40-54", count: 17278, weightedCount: 19681.8852663563, matchingSegment: 3}
]

list.reduce(function(a, b) {
     if(/^Male/.test(b['genderAge'])) {
        a['male']['pop'] += b['count'];
        a['male']['matchingSegment'] += b['matchingSegment'];
        a['male']['weightedCount'] += b['weightedCount'];
    } else if(/^Female/.test(b['genderAge'])){
        a['female']['pop'] += b['count'];
        a['female']['matchingSegment'] += b['matchingSegment'];
        a['female']['weightedCount'] += b['weightedCount'];
    }
     return a;
}, {'male':{'pop':0, 'matchingSegment':0, 'weightedCount':0}, 'female':{'pop':0, 'matchingSegment':0, 'weightedCount':0}});
0 голосов
/ 30 сентября 2018

Вот еще один простой подход lodash, который использует _. GroupBy и выполняет только один цикл:

var data = [ {genderAge: "Male 25-39", count: 13029, weightedCount: 18475.6824262314, matchingSegment: 2}, {genderAge: "Female 55+", count: 35639, weightedCount: 32294.5926147014, matchingSegment: 8}, {genderAge: "Female 25-39", count: 23285, weightedCount: 20645.0599977815, matchingSegment: 6}, {genderAge: "Female 18-24", count: 7745, weightedCount: 8497.30029399032, matchingSegment: 5}, {genderAge: "Male 55+", count: 38018, weightedCount: 28589.2793936886, matchingSegment: 4}, {genderAge: "Male 18-24", count: 4038, weightedCount: 8122.65161312996, matchingSegment: 1}, {genderAge: "Female 40-54", count: 23051, weightedCount: 22834.3167597392, matchingSegment: 7}, {genderAge: "Male 40-54", count: 17278, weightedCount: 19681.8852663563, matchingSegment: 3} ]

const getGenderTotals = data => {
   let Males = 0, Females = 0
   _.groupBy(data, (r => {/^Male/.test(r.genderAge) ? Males += r.count : Females += r.count}))
   return { Males, Females }
}

console.log(getGenderTotals(data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Поскольку у нас есть доступ к значению, и мы находимся в контексте _.groupBy, вы также можете легко вернуть Male или Female внутри groupBy iteratee.функция для получения фактических групп и т. д.

0 голосов
/ 28 сентября 2018

const { Sum, mreduceMap, compose, propOr, ifElse, constant } = crocks

const data = [
  {text: "Male 18-24 (12886)", value: "test_1", total: 12886},
  {text: "Male 25-39 (27913)", value: "test_2", total: 27913},
  {text: "Male 40-54 (29793)", value: "test__3", total: 29793},
  {text: "Male 55+ (54888)", value: "test__4", total: 54888},
  {text: "Female 18-24 (19354)", value: "test_5", total: 19354},
  {text: "Female 25-39 (43972)", value: "test_6", total: 43972},
  {text: "Female 40-54 (39327)", value: "test_7", total: 39327},
  {text: "Female 55+ (52263)", value: "test_8", total: 52263}
]

const startsWith = x => str =>
  typeof str === 'string' &&
  str.startsWith(x)

const isSex = sex =>
  compose(startsWith(sex), propOr('', 'text'))

const totalFor = sex =>
  ifElse(isSex(sex), propOr(0, 'total'), constant(0))

const sumSex = sex =>
  mreduceMap(Sum, totalFor(sex))

const sumMales = sumSex('Male')
const sumFemales = sumSex('Female')

const males = sumMales(data)
const females = sumFemales(data)

console.log({males, females})
<script src="https://unpkg.com/crocks@0.10.1/dist/crocks.min.js"></script>

С библиотекой crocks вы можете использовать высокофункциональный подход для решения проблемы.

0 голосов
/ 28 сентября 2018

Вы можете просто инициализировать array двумя objects, первый для Male, а второй для Female.

let result = [{text: "Male", total:0}, {text: "Female", total:0}];

Затем заполнить его соответствующими данными с помощьюforEach цикл над вашим первым array.

array.forEach(function(a){
   if(a.genderAge.indexOf("Male")>-1){
      result[0].total += a.count;
   }else if(a.genderAge.indexOf("Female")>-1){
      result[1].total += a.count;
   }
});

Демо:

var array = [
{genderAge: "Male 25-39", count: 13029, weightedCount: 18475.6824262314, matchingSegment: 2},
{genderAge: "Female 55+", count: 35639, weightedCount: 32294.5926147014, matchingSegment: 8},
{genderAge: "Female 25-39", count: 23285, weightedCount: 20645.0599977815, matchingSegment: 6},
{genderAge: "Female 18-24", count: 7745, weightedCount: 8497.30029399032, matchingSegment: 5},
{genderAge: "Male 55+", count: 38018, weightedCount: 28589.2793936886, matchingSegment: 4},
{genderAge: "Male 18-24", count: 4038, weightedCount: 8122.65161312996, matchingSegment: 1},
{genderAge: "Female 40-54", count: 23051, weightedCount: 22834.3167597392, matchingSegment: 7},
{genderAge: "Male 40-54", count: 17278, weightedCount: 19681.8852663563, matchingSegment: 3}
];

let result = [{text: "Male", total:0}, {text: "Female", total:0}];

array.forEach(function(a){
   if(a.genderAge.indexOf("Male")>-1){
      result[0].total += a.count;
   }else if(a.genderAge.indexOf("Female")>-1){
      result[1].total += a.count;
   }
});

console.log(result);
0 голосов
/ 28 сентября 2018

ES6

.reduce((acc,e)=>{
  if (/^Male/.test(e.text)){
   acc[0].total+=e.total
  }
  if (/^Female/.test(e.text)){
   acc[1].total+=e.total
  }
  return acc
},[{total:0},{total:0}])
0 голосов
/ 28 сентября 2018

Вы можете сгруппировать по требуемому значению и получить сумму total.

var data = array = [{ text: "Male 18-24 (12886)", value: "test_1", total: 12886 }, { text: "Male 25-39 (27913)", value: "test_2", total: 27913 }, { text: "Male 40-54 (29793)", value: "test__3", total: 29793 }, { text: "Male 55+ (54888)", value: "test__4", total: 54888 }, { text: "Female 18-24 (19354)", value: "test_5", total: 19354 }, { text: "Female 25-39 (43972)", value: "test_6", total: 43972 }, { text: "Female 40-54 (39327)", value: "test_7", total: 39327 }, { text: "Female 55+ (52263)", value: "test_8", total: 52263 }],
    result = _(data)
        .groupBy(o => o.text.match(/^\S+/)[0])
        .map((array, group) => ({ group, sum: _.sumBy(array, 'total') }))
        .value();

    console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
0 голосов
/ 28 сентября 2018
function sumFor(pattern, data) {
  return data
    .filter(item => item.text.match(pattern))
    .reduce((accu, item) => accu + item.total, 0);
}
sumFor(/^Male/, data); // 125480
sumFor(/^Female/, data); // 154916
...