How to select duplicated items

Viewed 65

I have a problem with

IEnumerable<SelectedProductRequest> selectedProducts = {
new SelectedProductRequest {id = 4, Name = "product1", Price = 23},
new SelectedProductRequest {id = 4, Name = "product1", Price = 44},
new SelectedProductRequest {id = 5, Name = "product2", Price = 11}
}

List<MyProducts> myProducts= {
new MyProducts{id = 4, Name = "product1", isExcl= true},
new MyProducts{id = 5, Name = "product2", isExcl= false}
}

IEnumerable<SelectedProductViewModel> products = myProducts
      .Select(product => new SelectedProductViewModel(
                            product.Name,
                            selectedProducts.FirstOrDefault(selectedProduct => selectedProduct.id== product.id)?.Price ?? 0,
                            product.IsExclusive))
                        .OrderByDescending(product => product.id)))

The products should return:

products= {
new SelectedProductRequest {id = 4, Name = "product1", Price = 23, IsExclusive = true},
new SelectedProductRequest {id = 4, Name = "product1", Price = 44, IsExclusive = true},
new SelectedProductRequest {id = 5, Name = "product2", Price = 11, IsExclusive = false}
}

What I get :

products= {
new SelectedProductRequest {id = 4, Name = "product1", Price = 23, IsExclusive = true},
new SelectedProductRequest {id = 5, Name = "product2", Price = 11, IsExclusive = false}
}

And that's because of the FirstOrDefault, Do you have any idea of how can I achieve the wanted result?

2 Answers

You can try additionally iterate through initial massive instead of FirstOrDefault:

IEnumerable<SelectedProductViewModel> products = myProducts
                .Select(product => selectedProducts.Where(selectedProduct => selectedProduct.id == product.id).Select(
                    resultProduct => new SelectedProductViewModel(
                        product.Name,
                        resultProduct?.Price ?? 0,
                        product.isExcl)))

Based on the shown linq, what you get is as expected. You call select on a collection with 2 items, so 2 items will be retruned

Use a Linq Join on the id to get the desired output.

IEnumerable<SelectedProductViewModel> products = myProducts
    .Join(selectedProducts, product => product.id, selected => selected.id, (product, selected) =>
        new SelectedProductViewModel(product.Name, selected?.Price ?? 0, product.IsExclusive)
    );

Given that an Id is not passed to the view model, the order would need to be done before the join.

Related