Reputation: 13367
So, I have this list of products in JSON:
var products = JArray.Parse(@"[{
id: 1,
name: 'Product 1',
variantId: 1
}, {
id: 2,
name: 'Product 2',
variantId: 1
}, {
id: 3,
name: 'Product 3',
variantId: 1
}, {
id: 4,
name: 'Product 4',
variantId: 4
}, {
id: 5,
name: 'Product 5',
variantId: 4
}]");
And it is read into my API as a list of JObject
. Currently I do this:
var sortedProducts = _sortProvider.SortByDrive(products, questions);
var productsToRemove = new List<JObject>();
var variant = "________NOTHING________";
for (var i = sortedProducts.Count - 1; i >= 0; i--)
{
var product = sortedProducts[i];
var productVariant = product.SelectToken("variant").ToString();
if (productVariant.Equals(variant))
productsToRemove.Add(product);
variant = productVariant;
}
products.RemoveAll(x => productsToRemove.Contains(x));
But I I want to use Linq to get the products (to remove). For the code above you should see that basically I want it to get all products that have the same variantId but skip the first one. So in the example above, it should return this:
var products = JArray.Parse(@"[{
id: 2,
name: 'Product 2',
variantId: 1
}, {
id: 3,
name: 'Product 3',
variantId: 1
}, {
id: 5,
name: 'Product 5',
variantId: 4
}]");
I hope that makes sense.
Upvotes: 0
Views: 267
Reputation: 13773
The other answer, while it will usually work, is not guaranteed to work. It assumes that the first item in a group is always the "master" item.
But this will break if the parent is not the first item in its group, e.g.:
var products = JArray.Parse(@"[{
id: 2,
name: 'Product 2', //SWAPPED
variantId: 1
}, {
id: 1,
name: 'Product 1', //SWAPPED
variantId: 1
}, {
id: 3,
name: 'Product 3',
variantId: 1
}, {
id: 4,
name: 'Product 4',
variantId: 4
}, {
id: 5,
name: 'Product 5',
variantId: 4
}]");
To be fair to @Stop-Cran, you did explicitly ask to exclude the "first" item. He answered the question as it was asked, but I doubt that's the actual problem you're trying to solve.
It seems like you want to exclude the "master" variant of a product line, i.e. the products who have themselves set as their variantId
.
Going by those criteria, a more guaranteed approach would be to use that trait (obj.Id == obj.variantId
) to exclude them:
new JArray(sortedProducts.Where(p => p.id != p.variantId));
Upvotes: 0
Reputation: 4408
Group by variantId
and select all items except first from each of the groups (and enclose with JArray
if you need to return JSON):
new JArray(sortedProducts.GroupBy(p => p["variantId"]).SelectMany(g => g.Skip(1)));
This yields for me:
[{
"id": 2,
"name": "Product 2",
"variantId": 1
},
{
"id": 3,
"name": "Product 3",
"variantId": 1
},
{
"id": 5,
"name": "Product 5",
"variantId": 4
}]
Upvotes: 3