我需要从现有数组中提取数据,以仅过滤数量为reference_id
的每个项目的年份和> 0
。
我的sample_array
包含以下数据:
var sample_array = [{
'reference_id': 1,
'products': [{
year: 1,
quantity: 0
}, {
year: 2009,
quantity: 5
}]
}, {
'reference_id': 2,
'products': [{
year: 2009,
quantity: 0
}]
}, {
'reference_id': 3,
'products': [{
year: 1,
quantity: 0
}, {
year: 2009,
quantity: 5
}]
}, {
'reference_id': 4,
'products': [{
year: 2014,
quantity: 10
}, {
year: 2015,
quantity: 6
}]
}];
为了让我提取所需数据的方式,我两次使用_.each
(在少数项目中仍使用 underscore.js )先进行过滤,然后重新构建year
和reference_id
组成的数组。
var references = [];
_.each(sample_array, function(reference) {
reference_products = _.filter(reference.products, function(data) {
return data.quantity > 0;
});
if (!_.isEmpty(reference_products))
_.each(reference_products, function(product) {
references.push({
'reference_id': reference.reference_id,
'year': product.year
});
});
});
它可以正常工作,但是我认为使用_.reduce
购买数组引用可能是一种更为优雅的方法,但是我没有找到实现它的方法。
预期的结果将是console.log(references)
:
[{
reference_id: 1
year: 2009
} {
reference_id: 3
year: 2009
} {
reference_id: 4
year: 2014
} {
reference_id: 4
year: 2015
}]
任何提示吗?
答案 0 :(得分:3)
reduce
将不必要地使代码复杂化,因为您必须手动收集结果。取而代之的是,您可以通过map
对数组进行平移来创建仅包含所需值的中间数组,然后对其进行展平来表示这一点:
var sample_array = [{
'reference_id': 1,
'products': [{
year: 1,
quantity: 0
}, {
year: 2009,
quantity: 5
}]
}, {
'reference_id': 2,
'products': [{
year: 2009,
quantity: 0
}]
}, {
'reference_id': 3,
'products': [{
year: 1,
quantity: 0
}, {
year: 2009,
quantity: 5
}]
}, {
'reference_id': 4,
'products': [{
year: 2014,
quantity: 10
}, {
year: 2015,
quantity: 6
}]
}];
const combined = _.map(
sample_array,
(e) => // for each first-level element...
_.chain(e.products) // look at its `products` array...
.filter((p) => p.quantity > 0) // keeping only those with a quantity > 0
.map((p) => { // and now return the result of mapping over that array of products
return {
reference_id: e.reference_id,
year: p.year
};
})
.value());
console.log(combined);
// the above value is an array of arrays (one per first-level
// element), so we need to flatten it
const references = _.flatten(combined, true);
console.log(references);
(我在转换函数内部使用了_.chain
,以使流程更清晰。)
答案 1 :(得分:1)
这是我使用reduce
,filter
和map
解决问题的另一种方法。
const references = [{
'reference_id': 1,
'products': [{
year: 1,
quantity: 0
}, {
year: 2009,
quantity: 5
}]
}, {
'reference_id': 2,
'products': [{
year: 2009,
quantity: 0
}]
}, {
'reference_id': 3,
'products': [{
year: 1,
quantity: 0
}, {
year: 2009,
quantity: 5
}]
}, {
'reference_id': 4,
'products': [{
year: 2014,
quantity: 10
}, {
year: 2015,
quantity: 6
}]
}];
const result = references.reduce((acc, reference) => {
const { reference_id, products } = reference;
const productsWithQuantity = products.filter(product => product.quantity > 0);
const productsWithReference = productsWithQuantity.map(product => ({ reference_id: reference_id, year: product.year}));
return [...acc, ...productsWithReference];
}, []);
console.log(result);