Reputation: 5261
I have a collection initialized like this:
var invoices = new Array();
var invoice = new Invoice();
invoice.number = "123";
invoice.date = "2016-05-03";
invoice.amount = "100";
var products = new Products();
var product = new Product();
product.code = "A";
product.name = "bar";
products.push(product);
var product2 = new Product();
product2.code = "B";
product2.name = "foo";
products.push(product2);
invoice.products = products;
Now I got to filter by the properties of the invoice like this.
var filtered = invoices.filter(function(invoice){
return invoice.number == "123";
});
But now I want to get the invoice that matches with number and the product name
How can I do this
var filtered = invoices.filter(function(invoice){
return invoice.number == "123"
// && invoice.products "name" == "foo"; //<-- At this level how can I filter?
});
Upvotes: 2
Views: 89
Reputation: 504
If you want to obtain a new list of invoices with filtered products inside you need to clone invoices instead of linking them with filter:
var filtered = []
invoices.forEach(function (invoice) {
if (invoice.number != "123") {
return;
}
var newInvoice = new Invoice();
newInvoice.number = invoice.number;
newInvoice.date = invoice.date;
newInvoice.amount = invoice.amount;
var newProducts = invoice.products.filter(function (product) {
return product.name == "foo"
});
newInvoice.products = newProducts
filtered.push(newInvoice)
});
UPD: as John said, if you want to filter invoices by the rule like: "Get all invoices that has number equal to 123 and has at least one product named "foo" this is the solution:
var filtered = invoices.filter(function(invoice){
return invoice.number == "123" && invoice.products.some(function (p) {
return p.name == "foo";
});
});
Upvotes: 0
Reputation: 483
var filtered = invoices.filter(function(invoice){
return invoice.number == "123" && invoice.products.some(function (p) {
return p.name == "foo";
});
});
Upvotes: 1
Reputation: 155363
Use Array.some
to check for the presence of a product with the desired name:
var filtered = invoices.filter(function(invoice){
return invoice.number == "123" && invoice.products.some(function(prod) {
return prod.name === 'foo';
});
});
Unlike using Array.filter
and checking the length
of the resulting array, this avoids creating a temporary array at all, and short-circuits; as soon as it finds a hit, it returns true immediately.
Upvotes: 6