获取匹配数组元素的总值

时间:2018-09-18 08:35:54

标签: javascript arrays

这是我当前的数组

0:{modelNumber: "123456789", balance: { amount:1000, currency:"EUR" }}
1:{modelNumber: "987654321", balance: { amount:2000, currency:"EUR" }}
2:{modelNumber: "322353466", balance: { amount:1500, currency:"GBP" }}
3:{modelNumber: "892347522", balance: { amount:1000, currency:"USD" }}
4:{modelNumber: "931883113", balance: { amount:3000, currency:"INR" }}
5:{modelNumber: "854300564", balance: { amount:2500, currency:"GBP" }}
6:{modelNumber: "931883113", balance: { amount:3000, currency:"INR" }}
7:{modelNumber: "854300564", balance: { amount:3500, currency:"USD" }}

我正在尝试返回一个新的数组,其中包含每种货币以及每种货币的总价值。

像下面这样返回上面数组中每种货币的总金额

0:{currency: "EUR", totalAmount: 3500}
1:{currency: "GBP", totalAmount: 5000}
2:{currency: "USD", totalAmount: 4500}
3:{currency: "INR", totalAmount: 6000}

最初的方法是

//the current array
let theInitialArray = state.vehicle;

const results = theInitialArray.reduce((accumalator, current) => {
    const { currency } = current.balance;
    if (accumalator[currency]) {
        accumalator[currency].push(current);
        return accumalator;
    }
    accumalator[currency] = [current];
    return accumalator;     
}, {});

let frank =  Object.keys(results)
let jim = [];
let expectedOutput = theInitialArray.filter((x) => {
    for (let i=0; i < frank.length; i++) {
        if (x.balance.currency === frank[i]) {
            jim.push({'currency': frank[i], 'amount': x.balance.amount});
        }
    }
});
console.log('expectedOutput', expectedOutput)
return expectedOutput

7 个答案:

答案 0 :(得分:8)

Here is a O(n) approach of getting that output:

  1. You first define a empty object tempObj which will be used to store the currency and totalAmount value as a object based on the currency key
  2. Then, if this currency key is defined in the tempObj you will simply add the amount with the totalAmount for an existing object.
  3. Else you will create a object with the amount as totalAmount, currency as key of tempObj and currency as currency of the item in forEach loop
  4. Finally you will need to do Object.values(tempObj) so that we get the object values and ignore the keys of tempObj to get the desired result.

var arr = [{modelNumber: "123456789", balance: { amount:1000, currency:"EUR" }},
{modelNumber: "987654321", balance: { amount:2000, currency:"EUR" }},
{modelNumber: "322353466", balance: { amount:1500, currency:"GBP" }},
{modelNumber: "892347522", balance: { amount:1000, currency:"USD" }},
{modelNumber: "931883113", balance: { amount:3000, currency:"INR" }},
{modelNumber: "854300564", balance: { amount:2500, currency:"GBP" }},
{modelNumber: "931883113", balance: { amount:3000, currency:"INR" }},
{modelNumber: "854300564", balance: { amount:3500, currency:"USD" }}];

var tempObj = {};
arr.forEach((obj)=>{
  if(tempObj[obj.balance.currency]){
    tempObj[obj.balance.currency].totalAmount += obj.balance.amount
  } else {
    tempObj[obj.balance.currency] = {
      currency: obj.balance.currency,
      totalAmount : obj.balance.amount
    }
  }
});
var resArray = Object.values(tempObj);
console.log(resArray);

答案 1 :(得分:8)

您可以Array.reduce()迭代数据。如果累加器中不存在货币(reduce回调中的r),请对其进行初始化。将当前金额加到累加器中的货币金额中。使用Object.values获取多种货币:

const data = [{"modelNumber":"123456789","balance":{"amount":1000,"currency":"EUR"}},{"modelNumber":"987654321","balance":{"amount":2000,"currency":"EUR"}},{"modelNumber":"322353466","balance":{"amount":1500,"currency":"GBP"}},{"modelNumber":"892347522","balance":{"amount":1000,"currency":"USD"}},{"modelNumber":"931883113","balance":{"amount":3000,"currency":"INR"}},{"modelNumber":"854300564","balance":{"amount":2500,"currency":"GBP"}},{"modelNumber":"931883113","balance":{"amount":3000,"currency":"INR"}},{"modelNumber":"854300564","balance":{"amount":3500,"currency":"USD"}}];

const result = Object.values(data.reduce((r, { balance }) => {
  const { amount, currency } = balance;
  if(!r[currency]) r[currency] = { currency, amount: 0 };
  
  r[currency].amount += amount;
  
  return r;
}, {}));

console.log(result);

答案 2 :(得分:1)

使用Array.prototype.reduceObject.keys的简单解决方案:

  <!-- Presso -->
                    <div class="{!IF(presso, 'slds-show', 'slds-hide')}" style="margin-bottom: 8px">
                        <div class="slds-form-element slds-size--1-of-1">
                            <label class="slds-form-element__label">Presso</label>
                            <div class="slds-form-element__control">
                                <input id="pressoInput" class="slds-input" type="text" /> 
                            </div>
                        </div>
                    </div>

                    <!--  Region -->
                    <div class="slds-form-element">
                        <label class="slds-form-element__label">
                                Region
                        </label>
                        <div class="slds-form-element__control">
                            <input id="regionInput" class="slds-input" type="text" disabled="disabled"/>
                        </div>
                    </div>

答案 3 :(得分:0)

可以减少您拥有的值,并将它们映射为所需的格式:

const values = [
  {modelNumber: "123456789", balance: { amount:1000, currency:"EUR" }},
  {modelNumber: "987654321", balance: { amount:2000, currency:"EUR" }},
  {modelNumber: "322353466", balance: { amount:1500, currency:"GBP" }},
  {modelNumber: "892347522", balance: { amount:1000, currency:"USD" }},
  {modelNumber: "931883113", balance: { amount:3000, currency:"INR" }},
  {modelNumber: "854300564", balance: { amount:2500, currency:"GBP" }},
  {modelNumber: "931883113", balance: { amount:3000, currency:"INR" }},
  {modelNumber: "854300564", balance: { amount:3500, currency:"USD" }},
];

const results = values.reduce((prev, curr) => ({
  ...prev,
  [curr.balance.currency]: (prev[curr.balance.currency] || 0) + curr.balance.amount
}), {})

const inCorrectFormat = Object.keys(results).map(key => ({
  currency: key,
  totalAmount: results[key]
}))

console.dir(inCorrectFormat)

答案 4 :(得分:0)

您可以使用Map并将currency / totalAmount对的所需数组呈现为新对象。

var data = [{ modelNumber: "123456789", balance: { amount: 1000, currency: "EUR" } }, { modelNumber: "987654321", balance: { amount: 2000, currency: "EUR" } }, { modelNumber: "322353466", balance: { amount: 1500, currency: "GBP" } }, { modelNumber: "892347522", balance: { amount: 1000, currency: "USD" } }, { modelNumber: "931883113", balance: { amount: 3000, currency: "INR" } }, { modelNumber: "854300564", balance: { amount: 2500, currency: "GBP" } }, { modelNumber: "931883113", balance: { amount: 3000, currency: "INR" } }, { modelNumber: "854300564", balance: { amount: 3500, currency: "USD" } }],
    result = Array.from(
        data.reduce((m, { balance: { amount, currency } }) =>
            m.set(currency, (m.get(currency) || 0) + amount), new Map),
        ([currency, totalAmount]) => ({ currency, totalAmount })
    );

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

答案 5 :(得分:0)

这使用两个数组,将一个(货币)中的货币的唯一名称压入另一个(结果)中的对象。

a = [{modelNumber: "123456789", balance: { amount:1000, currency:"EUR" }}, {modelNumber: "987654321", balance: { amount:2000, currency:"EUR" }},{modelNumber: "322353466", balance: { amount:1500, currency:"GBP" }},{modelNumber: "892347522", balance: { amount:1000, currency:"USD" }},{modelNumber: "931883113", balance: { amount:3000, currency:"INR" }},{modelNumber: "854300564", balance: { amount:2500, currency:"GBP" }},{modelNumber: "931883113", balance: { amount:3000, currency:"INR" }},{modelNumber: "854300564", balance: { amount:3500, currency:"USD" }}]

let currencies = [], result = [];
a.map((v)=>{
  let {currency, amount} = v.balance;
  if(!currencies.includes(currency)){
    currencies.push(currency);
    result.push({currency, totalAmount:amount});
  }else{
    result[currencies.findIndex(vv=>vv===currency)].totalAmount+=amount;
  }
})

答案 6 :(得分:-1)

我的本​​机数组方法mapfilterreduce的解决方案

const res = arr
  // map to currency
  .map(i => i.balance.currency)
  // get unique currency
  .filter((v, i, a) => a.indexOf(v) === i)
  // map to result
  .map((i, a) => ({
    currency: i,
    totalAmount: calcTotalAmount(i)
  }));

// calculate amount
function calcTotalAmount(currency) {
  return (
    arr
      // filter to current curency
      .filter(i => i.balance.currency === currency)
      // reduce to number
      .reduce((accum, i) => accum + i.balance.amount, 0)
  );
}