Reputation: 13387
I am trying to sort a list of objects like this:
products.Sort((a, b) =>
{
var x = string.CompareOrdinal(a.SelectToken("model").ToString(), b.SelectToken("model").ToString());
var z = string.CompareOrdinal(b.SelectToken("colour").ToString(), colour);
return x > 0 ? z : x;
});
and then I want to loop through the list in reverse so I can remove duplicates:
// Loop through products in reverse
for (var i = products.Count() - 1; i >= 0; i--)
{
// Get our product
var product = products[i];
// Get our product colour
var productColour = product.SelectToken("colour").ToString();
// If our colour is black
if (colour == "Black")
{
// If the product colour is not black, remove the duplicate product
if (!productColour.Equals(colour))
products.RemoveAt(i);
}
else
{
// Get our product model
var productModel = product.SelectToken("model").ToString();
// If we are the same model but a different colour, remove the duplicate
if (productModel.Equals(model) && !productColour.Equals(colour))
products.RemoveAt(i);
// Update our variable
model = productModel;
}
}
But it isn't just that simple. The colour variable is by default "Black" but can be set to any colour really. So, I want to sort by model first and then by colour, but I would like to have it so that it sorts the colours like this. If the colour is "Pink" the list should be like this:
[{
colour: 'Any'
},{
colour: 'Any'
},{
colour: 'Any'
},{
colour: 'Black'
},{
colour: 'Black'
},{
colour: 'Pink'
}]
So basically, if the colour selected is not black, it should be at the bottom of the sort and directly followed by Black (all other colours come before these two). If the colour selected is black, then black should be at the bottom of the list. Can someone help me out with this?
Just for information, this is an example of one of the items that will be sorted:
{
"id": 3797,
"title": "Canon EOS 100D Digital SLR Camera with 18-55 IS STM Lens, HD 1080p, 18MP, 3\" LCD Touch Screen",
"shortTitle": "Canon EOS 100D Black",
"brand": "Canon",
"model": "EOS 100D",
"colour": "Black",
"gtin": "8714574602721",
"image": "http://piiick.blob.core.windows.net/images/Canon-EOS-100D-18-55-Black-8714574602721.png",
"type": "Digital SLR",
"lensFocalLength": "18-55",
"lensType": "IS STM",
"lensMount": "EF/EF-S",
"maxAperture": "999",
"connectivity": "",
"shootingModes": "Scene Intelligent Auto (Stills and Movie), No Flash, Creative Auto, Portrait, Landscape, Close-up, Sports, SCN(Kids, Food, Candlelight, Night Portrait, Handheld Night Scene, HDR Backlight Control), Program AE , Shutter priority AE, Aperture priority AE, Manual (Stills and Movie)",
"weight": 410.0,
"width": 116.8,
"height": 90.7,
"depth": 69.4,
"digitalZoom": "N/A",
"opticalZoom": "N/A",
"waterproof": false,
"maxVideoResolution": "1920 x 1080",
"sensorType": "CMOS",
"sensorSize": "22.3 x 14.9 mm",
"continuousShootingSpeed": "4",
"iso": "1600",
"style": "traditional",
"designer": "",
"dateAnnounced": "10/06/2008",
"focusPoints": 7
}
It is entirely possible that a product may not have a colour of black or the selected colour, but I don't want to remove it from my list (just the duplicate model).
Upvotes: 0
Views: 63
Reputation: 1015
if your intention is to remove duplicate, why not just use groupby?
string str = @"[{'model':'aaa', 'colour':'red'}
,{'model':'aaa', 'colour':'red'}
,{'model':'aaa', 'colour':'green'}
,{'model':'bbb', 'colour':'red'}]";
JArray allProducts = JArray.Parse(str);
//Get the first product of each group
var uniq = allProducts
.GroupBy(x => new { model = x["model"], colour = x["colour"] })
.Select(x => x.First())
.ToList();
or to filter by selected colour, add where clause
string colour = "red";
var uniq = allProducts
.GroupBy(x => new { model = x["model"], colour = x["colour"] })
.Select(x => x.First())
.Where(x => x["colour"].Value<string>() == colour)
.ToList();
Upvotes: 0
Reputation: 10060
Your sorting algorithm should be changed in order to fit what you want.
What I understood is that you sort by model then you sort by color among the same models but selectedColor
should be at the bottom. However, black color should be right above the selected color. I think removing duplicates shouldn't be a problem.
Swap 1 and -1 if necessary.
products.Sort((a, b) =>
{
var x = string.CompareOrdinal(a.SelectToken("model").ToString();
If (x!=0) return x;
if (a.color == selectedColor){
return 1
}
if (b.color == selectedColor){
return -1
}
if (a.color == "black") {
return 1
}
if (b.color == "black") {
return -1
}
return string.CompareOrdinal(b.SelectToken("colour").ToString(), colour);
});
Upvotes: 1