How to only return specific object list base on the condition - c#

I want to add a condition to for returning selected object list. If the condition is met, it will not return the an item if its category is for this example, category is 3.
This is the query:
var objectQuery = query
.ToList()
.Select(a => new
{
a.Id,
ObjectDetails = (new ObjectClass[] { })
.Concat(...)
.Concat(...)
.Distinct()
.Select(f => new
{
f.ObjectDetails.Id,
f.ObjectDetails.Name,
f.ObjectDetails.DisplayName,
category = (int)f.ObjectDetails.Category,
f.ObjectDetails.IsArchived,
})
});
return objectQuery.ToList().FirstOrDefault();
i want to add a condition like this where if it met the condition, it will remove all items with category 3 and returns all the item if not, but i dont know how to properly implement it:
if(condition a)
return objectQuery.Select(...Where(category != 3)).ToList().FirstOrDefault();
else
return objectQuery.ToList().FirstOrDefault();
this is the return output:
{
"objectQuery": {
"id": 1198,
"ObjectDetails": [
{
"id": 1,
"name": "name one",
"displayName": "NAME 1",
"Category": 1,
},
{
"id": 2,
"name": "name two",
"displayName": "NAME 2",
"Category": 1,
},
{
"id": 3,
"name": "name three",
"displayName": "NAME 3",
"Category": 2,
},
{
"id": 4,
"name": "name four",
"displayName": "NAME 4",
"Category": 2,
},
{
"id": 5,
"name": "name five",
"displayName": "NAME 5",
"Category": 3,
},
{
"id": 6,
"name": "name six",
"displayName": "NAME 6",
"Category": 1,
},
{
"id": 7,
"name": "name seven",
"displayName": "NAME 7",
"Category": 1,
}
]
}
}

If I get your question properly then you'll need something like this:
var objectQuery = query
.ToList()
.Select(a => new
{
a.Id,
ObjectDetails = (new ObjectClass[] { })
.Concat(...)
.Concat(...)
.Distinct()
.Select(f => new
{
f.ObjectDetails.Id,
f.ObjectDetails.Name,
f.ObjectDetails.DisplayName,
category = (int)f.ObjectDetails.Category,
f.ObjectDetails.IsArchived,
})
.Where(f => !condition || f.category != 3)
});
return objectQuery.ToList().FirstOrDefault();

Related

LINQ. ordered list by key group but first group are with condition [duplicate]

This question already has answers here:
Linq Order by a specific number first then show all rest in order
(6 answers)
Closed yesterday.
I"m have List ordered by key group.
var productList = CustomerData.Data.Products
.GroupBy(x => x.CategoryDesc)
.OrderBy(x => x.Key)
.ToDictionary(x => x.Key, x => x.ToList());
it's good working
And i want one SPECIFIC group (with sale) set as first in the list.
But the rest of the groups to stay sorted in descending order.
something like that:
***I wrote in the format for the convenience of seeing
[
{
"Key": "SPECIFIC",
"Value": [
{
"SubGroup": "wire cutters",
"Model": "A",
"Price": "65"
},
{
"SubGroup": "hammers",
"Model": "B",
"Price": "71"
},
{
"SubGroup": "hammers",
"Model": "C",
"Price": "92.5"
},
]
},
{
"Key": "Rank A",
"Value": [
{
"SubGroup": "hammers",
"Model": "A",
"Price": "130"
},
{
"SubGroup": "hammers",
"Model": "B",
"Price": "142"
},
{
"SubGroup": "hammers",
"Model": "C",
"Price": "185"
},
]
},
{
"Key": "Rank B",
"Value": [
{
"SubGroup": "pliers",
"Model": "A",
"Price": "95"
},
{
"SubGroup": "pliers",
"Model": "B",
"Price": "59"
},
{
"SubGroup": "pliers",
"Model": "C",
"Price": "65"
},
]
},
{
"Key": "Rank C",
"Value": [
{
"SubGroup": "saws",
"Model": "A",
"Price": "905"
},
{
"SubGroup": "saws",
"Model": "B",
"Price": "589"
},
{
"SubGroup": "saws",
"Model": "C",
"Price": "655"
},
]
},
]
Add additional Order. First for detecting specific items, ThenBy for the rest.
var productList = CustomerData.Data.Products
.GroupBy(x => x.CategoryDesc)
.OrderByDescending(x => x.Key == "SPECIFIC")
.ThenBy(x => x.Key)
.ToDictionary(x => x.Key, x => x.ToList());

C# Json LinQ - Build Json String Using Loop

I am trying to produce a Json string that looks like this:
{
"fromAddress": {
"streetLines": [
"100 Test St",
"Ste 100"
],
"city": "Orlando",
"stateOrProvinceCode": "FL",
"postalCode": "32819",
"countryCode": "US"
},
"toAddress": {
"streetLines": [
"101 Test St",
null
],
"city": "Orlando",
"stateOrProvinceCode": "FL",
"postalCode": "32819",
"countryCode": "US"
},
"packageDimensions": [
{
"weight": 20.0,
"length": "18",
"width": "12",
"height": "13"
},
{
"weight": 20.0,
"length": "18",
"width": "12",
"height": "13"
},
{
"weight": 20.0,
"length": "18",
"width": "12",
"height": "13"
}
]
}
I've gotten this far with my code:
var json = new
{
fromAddress = new
{
streetLines = new[]
{
fromAddress1,
fromAddress2
},
city = fromCity,
stateOrProvinceCode = fromState,
postalCode = fromZip,
countryCode = fromCountry
},
toAddress = new
{
streetLines = new[]
{
toAddress1,
toAddress2
},
city = toCity,
stateOrProvinceCode = toState,
postalCode = toZip,
countryCode = toCountry
},
};
That produces the following, which is lacking the pack dimensions:
{
"fromAddress": {
"streetLines": [
"100 Test St",
"Ste 100"
],
"city": "Orlando",
"stateOrProvinceCode": "FL",
"postalCode": "32819",
"countryCode": "US"
},
"toAddress": {
"streetLines": [
"101 Test St",
null
],
"city": "Orlando",
"stateOrProvinceCode": "FL",
"postalCode": "32819",
"countryCode": "US"
}
}
My data for the pack dimensions are stored thusly:
List<double> weight
string length
string width
string height
Multiple values for weight are passed in with the List, the dimensions are constants.
I need to find a way to add the pack dimensions, iterating through the weight List to do so. But I'm not sure how to approach it, adding a loop in the Json build doesn't work in any way.
I would appreciate any advice on getting the data iteration that I need. Thanks.
You have to add LINQ expression with projection:
var json = new
{
fromAddress = new
{
streetLines = new[]
{
fromAddress1,
fromAddress2
},
city = fromCity,
stateOrProvinceCode = fromState,
postalCode = fromZip,
countryCode = fromCountry
},
toAddress = new
{
streetLines = new[]
{
toAddress1,
toAddress2
},
city = toCity,
stateOrProvinceCode = toState,
postalCode = toZip,
countryCode = toCountry
},
packageDimensions = weight.Select(w => new
{
weight = w,
length = length,
width = width,
height = height
})
.ToArray()
};

Zip collections matching by ID

This is a repost of a previous question that was wrongly closed as a duplicate:
Say I have two collections of the same type similar to the following:
OldCollection: [{ID: 1, other props}, {ID: 2, other props}, {ID: 3, other props}]
NewCollection: [{ID: 1, other props}, {ID: 3, other props}, {ID: 4, other props}]
Is there a way to zip the collections matching ID's to get a Tuple result like the following:
[{OLD-ID1, NEW-ID1},
{OLD-ID2, null},
{OLD-ID3, NEW-ID3},
{null, NEW-ID4}]
So basically I want to zip the collections together matching on ID and if only one collection has an entry with a particular ID the Tuple should fill in null for that spot.
IMPORTANT: This is not a duplicate of the full outer join solution. I do not want to combine my results so that Col1-ID1 gets merged with Col2-ID1. I Just want to Tuple them so I can see them side by side. Think of it as Collection 1 is the old values and Collection 2 is the new values. I want them to be paired up into Tuples so I can see ID1 and ID3 were updated, ID2 was removed, and ID4 was added.
Here is a DotNetFiddle example that almost does what I want.
The results of that fiddle is:
[
{
"Item1": {
"id": 1,
"name": "firstOld"
},
"Item2": {
"id": 1,
"name": "firstNew"
}
},
{
"Item1": {
"id": 2,
"name": "secondOld"
},
"Item2": {
"id": 3,
"name": "thirdNew"
}
},
{
"Item1": {
"id": 3,
"name": "thirdOld"
},
"Item2": {
"id": 4,
"name": "fourthNew"
}
},
{
"Item1": null,
"Item2": {
"id": 5,
"name": "fifthNew"
}
}
]
What I want is this:
[
{
"Item1": {
"id": 1,
"name": "firstOld"
},
"Item2": {
"id": 1,
"name": "firstNew"
}
},
{
"Item1": {
"id": 2,
"name": "secondOld"
},
"Item2": null
},
{
"Item1": {
"id": 3,
"name": "thirdOld"
},
"Item2": {
"id": 3,
"name": "thirdNew"
}
},
{
"Item1": null,
"Item2": {
"id": 4,
"name": "fourthNew"
}
},
{
"Item1": null,
"Item2": {
"id": 5,
"name": "fifthNew"
}
}
]
You want a full-outer-join anyway, but you could use this easy approach:
var oldByID = oldCollection.ToDictionary(x => x.Id);
var newByID = newCollection.ToDictionary(x => x.Id);
IEnumerable<int> allIds = oldByID.Keys.Union(newByID.Keys);
var oldAndNew = allIds.Select(id =>
(Old: oldByID.TryGetValue(id, out var oldObj) ? oldObj : null,
New: newByID.TryGetValue(id, out var newObj) ? newObj : null));
So first create two dictionaries to lookup the old and new objects via Id efficiently. Then collect all Id's and use Select to get the old/new object with each Id. If it's not available in the dictionary it will assign null to the tuple item.

Create dynamic pivot list using joins

I want to create dynamic pivot list on list which has data in below format
"products" :
{
"name": "ABC",
"Variance": [
{
"Date": "01-01-2018",
"Value": "10"
},
{
"Date": "02-01-2018",
"Value": "11"
},
{
"Date": "03-01-2018",
"Value": "12"
},
]
},
{
"name": "XYZ",
"Variance": [
{
"Date": "01-01-2018",
"Value": "22"
},
{
"Date": "03-01-2018",
"Value": "24"
},
{
"Date": "04-01-2018",
"Value": "28"
},
],
},
{
"name": "PQR",
"Variance": [
{
"Date": "01-01-2018",
"Value": "20"
},
{
"Date": "02-01-2018",
"Value": "22"
},
{
"Date": "04-01-2018",
"Value": "24"
},
],
}
I want to create pivot list so it can return data like
"NewProducts":[{
"Date": "01-01-2018",
"ABC" : "10"
"XYZ" : "22",
"PQR" : "20"
},
{
"Date": "02-01-2018",
"ABC" : "11"
"XYZ" : "null",
"PQR" : "22"
},
{
"Date": "03-01-2018",
"ABC" : "12"
"XYZ" : "24",
"PQR" : "null"
},
{
"Date": "04-01-2018",
"ABC" : "null"
"XYZ" : "28",
"PQR" : "24"
}]
I tried some approach of having joins on inner lists, but not getting required results. I want to avoid loops as my product list will vary as per selections.
I was able to join the list using for loops, but I want to have minimal use of for loops. Any suggestions would be really helpful to me.
Thanks in Advance.
Assuming you want to use a Dictionary<string,int> to hold the dynamic value pairs, you can use LINQ by first flattening the nested structure into a new flat list with SelectMany and then grouping by Date:
var ans = products.SelectMany(p => p.Variance.Select(v => new { p.name, v.Date, v.Value }))
.GroupBy(pv => pv.Date)
.Select(pvg => new { Date = pvg.Key, Fields = pvg.ToDictionary(p => p.name, p => p.Value) });

C# Json deserisalization

In C# how can I select only "GroupType" from the json below.
Thanks.
{
"QnACollection": {
"QnA": [
{
"id": 11,
"question": "What was your childhood nickname?"
},
{
"id": 12,
"question": "In what city was your mother born?"
},
{
"GroupType": "RUN",
"id": 45,
"question": "What is the first name?"
}
]
}
}
Using Json.Net
var value = (string)JObject.Parse(json)
.Descendants().OfType<JProperty>()
.FirstOrDefault(p => p.Name == "GroupType");

Categories