从表示股票、其现货价格和其他属性(如)的对象数组
stocks = [ { ticker: 'GOOG', price: 206, ... },
{ ticker: 'AAPL', price: 47, ... },
{ ticker: 'MSFT', price: 39, ... },
{ ticker: 'GOOG', price: 159, ... },
{ ticker: 'MSFT', price: 39, ... },
{ ticker: 'MSFT', price: 21, ... },
{ ticker: 'GOOG', price: 80, ... },
{ ticker: 'AAPL', price: 20, ... },
{ ticker: 'AAPL', price: 73, ... },
{ ticker: 'MSFT', price: 49, ... },
... ];
我想以函数的方式返回一个缩减数组,其中对于每个ticker,对象具有最大价格(以及其他属性)。
以下是我目前所拥有的:
c.reduce(function(acc, y) {
return acc
.filter(function(x) { return x.ticker!=y.ticker })
.concat(
acc.filter(function(x) { return x.ticker==y.ticker })
.concat([y])
.reduce(function(u,v) {
return u.price > v.price ? u : v } ) /* predicate */
)
}, []);
但是有没有一种更惯用的JavaScript方法呢?欢迎Undercore和lodash,但请不要jQuery。
使用lodash:
var res = _(stocks)
// group all elements by 'ticker'
.groupBy(function (s) {
return s.ticker;
// sort each group by price descending and get the first element (the max)
}).map(function (n) {
return _(n).sortBy(n, function (v) {
return -v.price;
}).first();
});
console.log(JSON.stringify(res, null, 4));
该代码给出:
[
{
"ticker": "GOOG",
"price": 206
},
{
"ticker": "AAPL",
"price": 73
},
{
"ticker": "MSFT",
"price": 49
}
]
较短版本排序ASC并获取最后一个元素:
var res = _(stocks)
.groupBy('ticker')
.map(function (n) {
return _(n).sortBy('price').last();
});
我尝试用函数概念来解决这个任务。
var stocks =
[
{ticker: 'GOOG', price: 206},
{ticker: 'AAPL', price: 47},
{ticker: 'MSFT', price: 39},
{ticker: 'GOOG', price: 159},
{ticker: 'MSFT', price: 39},
{ticker: 'MSFT', price: 21},
{ticker: 'GOOG', price: 80},
{ticker: 'AAPL', price: 20},
{ticker: 'AAPL', price: 73},
{ticker: 'MSFT', price: 49}
];
var result = stocks.reduce(function (acc, next) {
return acc
.filter(function (stock) {
return stock.ticker != next.ticker
})
.concat(acc.reduce(function (u, v) {
return u.ticker == v.ticker && u.price < v.price ? v : u;
}, next));
}, []);
console.log(result);
输出
[
{ ticker: 'GOOG', price: 206 },
{ ticker: 'AAPL', price: 73 },
{ ticker: 'MSFT', price: 49 }
]
这里是一个纯JavaScript解决方案,没有任何只使用一个filter()
和一个reduce()
:的框架
代码
var stocks = [ { ticker: 'GOOG', price: 206},
{ ticker: 'AAPL', price: 47},
{ ticker: 'MSFT', price: 39},
{ ticker: 'GOOG', price: 159},
{ ticker: 'MSFT', price: 39},
{ ticker: 'MSFT', price: 21},
{ ticker: 'GOOG', price: 80},
{ ticker: 'AAPL', price: 20},
{ ticker: 'AAPL', price: 73},
{ ticker: 'MSFT', price: 49}];
function max(arr) {
return arr.filter(function(item){
return this[item.ticker] === item;
}.bind(arr.reduce(function(res, cur) {
return (res[cur.ticker] = (res[cur.ticker]
? (res[cur.ticker].price > cur.price ? res[cur.ticker] : cur)
: cur
)), res;
}, {})));
}
console.log(max(stocks));
结果
[
{ ticker: 'GOOG', price: 206 },
{ ticker: 'AAPL', price: 73 },
{ ticker: 'MSFT', price: 49 }
]
JSBin
https://jsbin.com/linevudika/edit?js,控制台