我有这样的事情:
$scope.traveler = [
{ description: 'Senior', Amount: 50},
{ description: 'Senior', Amount: 50},
{ description: 'Adult', Amount: 75},
{ description: 'Child', Amount: 35},
{ description: 'Infant', Amount: 25 },
];
现在要获得这个数组的总数我正在做这样的事情:
$scope.totalAmount = function(){
var total = 0;
for (var i = 0; i < $scope.traveler.length; i++) {
total = total + $scope.traveler[i].Amount;
}
return total;
}
当只有一个数组时很容易,但我有其他数组,我想要总结一个不同的属性名称。
我会更开心如果我可以这样做:
$scope.traveler.Sum({ Amount });
但是我不知道如何通过这种方式来解决这个问题,我可以在将来重复使用它:
$scope.someArray.Sum({ someProperty });
答案
我决定使用@gruff-bunny建议,所以我avoid prototyping native object(数组)
我只是对他的答案做了一点修改,验证了数组,并且sum的值不为null,这是我的最终实现:
$scope.sum = function (items, prop) {
if (items == null) {
return 0;
}
return items.reduce(function (a, b) {
return b[prop] == null ? a : a + b[prop];
}, 0);
};
答案 0 :(得分:188)
我知道这个问题有一个可接受的答案,但我认为我会使用array.reduce替代使用Fiddle,看到汇总数组是减少的规范示例:
$scope.sum = function(items, prop){
return items.reduce( function(a, b){
return a + b[prop];
}, 0);
};
$scope.travelerTotal = $scope.sum($scope.traveler, 'Amount');
{{3}}
答案 1 :(得分:79)
另一种观点是,
Map
JavaScript函数Reduce
和var traveler = [{description: 'Senior', Amount: 50}, {description: 'Senior', Amount: 50}, {description: 'Adult', Amount: 75}, {description: 'Child', Amount: 35}, {description: 'Infant', Amount: 25}]; function amount(item){ return item.Amount; } function sum(prev, next){ return prev + next; } traveler.map(amount).reduce(sum); // => 235; // or use arrow functions traveler.map(item => item.Amount).reduce((prev, next) => prev + next);
是为了构建的(Map和Reduce是许多语言的强国)。
// Example of reuse.
// Get only Amounts greater than 0;
// Also, while using Javascript, stick with camelCase.
// If you do decide to go against the standards,
// then maintain your decision with all keys as in...
// { description: 'Senior', Amount: 50 }
// would be
// { Description: 'Senior', Amount: 50 };
var travelers = [{description: 'Senior', amount: 50},
{description: 'Senior', amount: 50},
{description: 'Adult', amount: 75},
{description: 'Child', amount: 35},
{description: 'Infant', amount: 0 }];
// Directly above Travelers array I changed "Amount" to "amount" to match standards.
function amount(item){
return item.amount;
}
travelers.filter(amount);
// => [{description: 'Senior', amount: 50},
// {description: 'Senior', amount: 50},
// {description: 'Adult', amount: 75},
// {description: 'Child', amount: 35}];
// Does not include "Infant" as 0 is falsey.
注意:通过制作单独的小功能,我们可以再次使用它们。
export function getCssUrl(){
return 'http://localhost/foo/foo.css';
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styles: ['@import "' +getCssUrl()+'"'],
encapsulation: ViewEncapsulation.None
})
export class AppComponent implements OnInit {}
答案 2 :(得分:65)
更新了答案
由于向Array原型添加函数的所有缺点,我正在更新此答案以提供一种替代方法,使语法与问题中最初请求的语法类似。
class TravellerCollection extends Array {
sum(key) {
return this.reduce((a, b) => a + (b[key] || 0), 0);
}
}
const traveler = new TravellerCollection(...[
{ description: 'Senior', Amount: 50},
{ description: 'Senior', Amount: 50},
{ description: 'Adult', Amount: 75},
{ description: 'Child', Amount: 35},
{ description: 'Infant', Amount: 25 },
]);
console.log(traveler.sum('Amount')); //~> 235
原始答案
由于它是一个数组,你可以向Array原型添加一个函数。
traveler = [
{ description: 'Senior', Amount: 50},
{ description: 'Senior', Amount: 50},
{ description: 'Adult', Amount: 75},
{ description: 'Child', Amount: 35},
{ description: 'Infant', Amount: 25 },
];
Array.prototype.sum = function (prop) {
var total = 0
for ( var i = 0, _len = this.length; i < _len; i++ ) {
total += this[i][prop]
}
return total
}
console.log(traveler.sum("Amount"))
答案 3 :(得分:56)
我总是避免更改原型方法和添加库,所以这是我的解决方案:
使用reduce Array原型方法就足够了
// + operator for casting to Number
items.reduce((a, b) => +a + +b.price, 0);
答案 4 :(得分:18)
我以为我会把这两分钱放在这上面:这是其中一个应该始终纯粹功能性的操作,而不是依赖于任何外部变量。一些人已经给出了一个很好的答案,使用reduce
就可以了。
由于我们大多数人已经可以负担得起使用ES2015语法,所以这是我的主张:
const sumValues = (obj) => Object.keys(obj).reduce((acc, value) => acc + obj[value], 0);
我们正在努力使其成为不可改变的功能。 reduce
在这里做的只是这样:
从累加器的值0
开始,并将当前循环项的值添加到它。
Yay for function programming and ES2015! :)
答案 5 :(得分:13)
您可以执行以下操作:
XAML1104 The type 'TreeViewNode' is not available in the target platform minimum version (10.0.15063.0) supported by this project
答案 6 :(得分:12)
使用带有重组的reduce来求和:
const traveler = [
{ description: 'Senior', Amount: 50 },
{ description: 'Senior', Amount: 50 },
{ description: 'Adult', Amount: 75 },
{ description: 'Child', Amount: 35 },
{ description: 'Infant', Amount: 25 },
];
console.log(traveler.reduce((n, {Amount}) => n + Amount, 0))
答案 7 :(得分:4)
我不确定这是否已被提及。但是有一个lodash功能。下面的片段,其中值是您要求的属性是'值'。
_.sumBy(objects, 'value');
_.sumBy(objects, function(o) { return o.value; });
两者都有效。
答案 8 :(得分:3)
它在TypeScript
和JavaScript
中为我工作:
let lst = [
{ description:'Senior', price: 10},
{ description:'Adult', price: 20},
{ description:'Child', price: 30}
];
let sum = lst.map(o => o.price).reduce((a, c) => { return a + c });
console.log(sum);
我希望是有用的。
答案 9 :(得分:2)
来自对象数组
function getSum(array, column)
let values = array.map((item) => parseInt(item[column]) || 0)
return values.reduce((a, b) => a + b)
}
foo = [
{ a: 1, b: "" },
{ a: null, b: 2 },
{ a: 1, b: 2 },
{ a: 1, b: 2 },
]
getSum(foo, a) == 3
getSum(foo, b) == 6
答案 10 :(得分:1)
这里是使用ES6箭头功能的单线。
const sumPropertyValue = (items, prop) => items.reduce((a, b) => a + b[prop], 0);
// usage:
const cart_items = [ {quantity: 3}, {quantity: 4}, {quantity: 2} ];
const cart_total = sumPropertyValue(cart_items, 'quantity');
答案 11 :(得分:1)
也可以使用Array.prototype.forEach()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<div class="line"></div>
<span></span>
</div>
<button>toggle</button>
答案 12 :(得分:0)
提高可读性并使用Map
和Reduce
的替代方法:
const traveler = [
{ description: 'Senior', amount: 50 },
{ description: 'Senior', amount: 50 },
{ description: 'Adult', amount: 75 },
{ description: 'Child', amount: 35 },
{ description: 'Infant', amount: 25 },
];
const sum = traveler
.map(item => item.amount)
.reduce((prev, curr) => prev + curr, 0);
可重复使用的功能:
const calculateSum = (obj, field) => obj
.map(items => items.attributes[field])
.reduce((prev, curr) => prev + curr, 0);
答案 13 :(得分:0)
这是我发现更灵活的解决方案:
function sumOfArrayWithParameter (array, parameter) {
let sum = null;
if (array && array.length > 0 && typeof parameter === 'string') {
sum = 0;
for (let e of array) if (e && e.hasOwnProperty(parameter)) sum += e[parameter];
}
return sum;
}
要获得总和,只需像这样使用它:
let sum = sumOfArrayWithParameter(someArray, 'someProperty');
答案 14 :(得分:0)
如何使用Java脚本求和对象数组
const traveler = [
{ description: 'Senior', Amount: 50},
{ description: 'Senior', Amount: 50},
{ description: 'Adult', Amount: 75},
{ description: 'Child', Amount: 35},
{ description: 'Infant', Amount: 25 }
];
const traveler = [
{ description: 'Senior', Amount: 50},
{ description: 'Senior', Amount: 50},
{ description: 'Adult', Amount: 75},
{ description: 'Child', Amount: 35},
{ description: 'Infant', Amount: 25 },
];
function sum(arrayData, key){
return arrayData.reduce((a,b) => {
return {Amount : a.Amount + b.Amount}
})
}
console.log(sum(traveler))
答案 15 :(得分:0)
我已经在使用jquery。但我认为它足够直观,只需:
var total_amount = 0;
$.each(traveler, function( i, v ) { total_amount += v.Amount ; });
这基本上只是@akhouri答案的简写形式。
答案 16 :(得分:0)
经过这些答案后,我认为实际上 for
(或 forEach
或 for of
with await
)循环比 reduce
更易读甚至 map
和 reduce
。
想想:
var traveler = [
{Amount: 50, description: 'Senior'},
{Amount: 50, description: 'Senior'},
{Amount: 75, description: 'Adult'},
{Amount: 35, description: 'Child'},
{Amount: 25, description: 'Infant'}
];
var sumFromArray = (propertyName, array) => {
let sum = 0;
array.forEach(item => {
sum += item[propertyName] ?? 0;
});
return sum;
};
var sumOfTraveler = sumFromArray('Amount', traveler);
console.log(sumOfTraveler);
使用类型您的函数定义可能如下所示:
const sumFromArray = (propertyName: string, array: Array<{[propertyName: string]: number}>) => { ... };
请参阅此处了解更多详情:TypeScript A computed property name in a type literal must directly refer to a built-in symbol
我不反对 map
、reduce
或 one-liners,这只是值得深思。
答案 17 :(得分:-3)
老实说,在阅读作为解决此问题的解决方案发布的所有代码时,我感到很沮丧。解决这个问题的简单方法是
let testArray = [5, 7, 8, 4];
function(){
sum = 0;
for(let i = 0; i < testArray.length; i++){
sum += testArray[i];
}
// 会给你数组的总和