-1

So, I have some data, which comes like this:

[
  {
    "Name": "Jonh ",
    "Order": [
      {
        "Product": {
          "Id": 8
        },
        "Quantity": 1
      },
      {
        "Product": {
          "Id": 19
        },
        "Quantity": 8
      }
    ]
  },
  {
    "Name": "Jane Doe 1",
    "Order": [
      {
        "Product": {
          "Id": 26
        },
        "Quantity": 7
      },
      {
        "Product": {
          "Id": 44
        },
        "Quantity": 2
      },
      {
        "Product": {
          "Id": 21
        },
        "Quantity": 6
      },
      {
        "Product": {
          "Id": 48
        },
        "Quantity": 2
      },
      {
        "Product": {
          "Id": 35
        },
        "Quantity": 2
      },
      {
        "Product": {
          "Id": 43
        },
        "Quantity": 1
      }
    ]
  }
]

UPDATE: the JSON is already parsed with NewtonSoft.Json.JsonConvert
I am completely new to Linq, i was able to do this in JavaScript. I need a linq query that extracts the sold products ordered by the most sold;
so: it aggregates every product and sums the quantity sold, and orders by the sum of the quantities.

This is what i have for now:

var products = clientSales.SelectMany(m => m.Order).Select(f=>f.Product.Id).Distinct();

which gives me a list of distinct productIds...

5

2 Answers 2

1

You were almost right, first you should use SelectMany in Order, then OrderByDescending in Quantity and finally Select to get product id, like the code below:

var products = clientSales.SelectMany(m => m.Order)
                          .OrderByDescending(x => x.Quantity)
                          .Select(p => p.Product.Id)
                          .Distinct();

Output:

19
26
21
44
48
35
8
43

You can see it working here: https://dotnetfiddle.net/6sb3VY

Sign up to request clarification or add additional context in comments.

Comments

1

Assuming you had the following classes:

public class Customer
{
    public string Name { get; set; }
    public List<Item> Order { get; set; }
}
public class Item
{
    public Product Product { get; set; }
    public int Quantity { get; set; }
}
public class Product
{
    public int Id { get; set; }
}

You can produce a list of product IDs and the quantity sold ordered by the quantity descending with the following:

 string json = "[{\"Name\": \"Jonh \",\"Order\": [{\"Product\": {\"Id\": 8},\"Quantity\": 1},{\"Product\": {\"Id\": 19},\"Quantity\": 8}]},{\"Name\": \"Jane Doe 1\",\"Order\": [{\"Product\": {\"Id\": 26},\"Quantity\": 7},{\"Product\": {\"Id\": 44},\"Quantity\": 2},{\"Product\": {\"Id\": 21},\"Quantity\": 6},{\"Product\": {\"Id\": 48},\"Quantity\": 2},{\"Product\": {\"Id\": 35},\"Quantity\": 2},{\"Product\": {\"Id\": 43},\"Quantity\": 1}]}]";

 var deserializedObject = JsonConvert.DeserializeObject<List<Customer>>(json);

 var groupedProducts = from product in deserializedObject.SelectMany(c => c.Order)
                       group product by product.Product.Id into grpProduct
                       select new
                       {
                            ProductId = grpProduct.Key,
                            Quantity = grpProduct.ToList().Sum(p => p.Quantity)
                       };

// Produces the ordered list of product IDs and quantity sold sorted by quantity descending
var orderedProducts = groupedProducts.OrderByDescending(p => p.Quantity).ToList();

This would end up producing the following list of anonymous objects based on your input:

Product ID      Quantity
19              8
26              7
21              6
44              2
48              2
35              2
8               1
43              1

3 Comments

Thank you, I will test it later with my real data
+1 This will give the correct result when multiple orders have the same product. But I don't see why you need ...orderby grpProduct.Count() descending... in groupedProducts?
@Sphinxxx You're right. You don't need the orderby clause there since the ordering is really done in orderedProducts. I edited my answer to remove it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.