Reputation: 111
This is my code:
public class Photos
{
public long PhotoLabel { get; set; }
public int UserID { get; set; }
}
List<Photos> photolist = new List<Photos>();
var result1 = photolist.OrderByDescending(p => p.PhotoLabel).ThenBy(r => r.UserID).ToList();
If I display the contents now, this is what I get (First sorted in descending order of PhotoLabel
and then sorted by UserID
:
|------|---------------------|---------------------|
| Row | UserID | PhotoLabel |
|----------------------------|---------------------|
| 1 | 92 | 20180729181046 |
|----------------------------|---------------------|
| 2 | 92 | 20180729181041 |
|----------------------------|---------------------|
| 3 | 92 | 20180729181037 |
|----------------------------|---------------------|
| 4 | 88 | 20180729174415 |
|----------------------------|---------------------|
| 5 | 88 | 20180729174405 |
|----------------------------|---------------------|
| 6 | 04 | 20180729174358 |
|----------------------------|---------------------|
| 7 | 1 | 20170924183847 |
|----------------------------|---------------------|
| 8 | 1 | 20170921231422 |
|----------------------------|---------------------|
| 9 | 1 | 20170920194624 |
|----------------------------|---------------------|
| 10 | 32 | 20170820114728 |
|----------------------------|---------------------|
| 11 | 32 | 20170820114725 |
|----------------------------|---------------------|
| 12 | 32 | 20170820114421 |
|----------------------------|---------------------|
| 13 | 32 | 20170820114416 |
|----------------------------|---------------------|
| 14 | 1 | 20170225151023 |
|----------------------------|---------------------|
| 15 | 1 | 20170225151000 |
|----------------------------|---------------------|
| 16 | 1 | 20170225150957 |
|----------------------------|---------------------|
From the sorted table above, this is what I want to achieve:
Display groups of UserIDs
and PhotoLabels
where UserIDs
appear 3 or more times in one group (eg: rows 4 and 5 where UserID=88
and row 6 where UserID=04
should be eliminated since the UserID=88
appears just twice in the group and UserID=04
appears only once in the group).
Display only the top most group of UserIDs
and exclude any repeating UserIDs
(eg: rows 7,8 and 9 displays the UserID=1
group. Don't display any other UserID=1
group such as rows 14,15 and 16. )
The expected result from query should be:
|------|---------------------|---------------------|
| Row | UserID | PhotoLabel |
|----------------------------|---------------------|
| 1 | 92 | 20180729181046 |
|----------------------------|---------------------|
| 2 | 92 | 20180729181041 |
|----------------------------|---------------------|
| 3 | 92 | 20180729181037 |
|----------------------------|---------------------|
| 7 | 1 | 20170924183847 |
|----------------------------|---------------------|
| 8 | 1 | 20170921231422 |
|----------------------------|---------------------|
| 9 | 1 | 20170920194624 |
|----------------------------|---------------------|
| 10 | 32 | 20170820114728 |
|----------------------------|---------------------|
| 11 | 32 | 20170820114725 |
|----------------------------|---------------------|
| 12 | 32 | 20170820114421 |
|----------------------------|---------------------|
| 13 | 32 | 20170820114416 |
|----------------------------|---------------------|
Thank you so much in in advance! :-)
Upvotes: 0
Views: 89
Reputation: 111
Thank you all for your help. SKLTFZ's and TanvirArjel's answers were close but didn't achieve the expected results. I realized that you cannot achieve everything described above in Linq, so this is what I came up with and it achieves everything listed above:
PS: I renamed var result1 to ordered_photolist
List<Photos> ordered_photolist = photolist.OrderByDescending(p => p.PhotoLabel).ThenBy(r => r.UserID).ToList();
List<Photos> temp_photolist = new List<Photos>();
List<Photos> final_photolist = new List<Photos>();
int UserID = -1;
int UserIDCount = 0;
foreach (Photos p in ordered_photolist)
{
if (UserID == -1)
{
UserID = p.UserID;
temp_photolist.Add(p);
UserIDCount++;
}
else
{
if ( UserID == p.UserID )
{
temp_photolist.Add(p);
UserIDCount++;
}
else
{
if ( UserIDCount >= 3 )
{
// add temp_photolist to final list
int index = final_photolist.FindIndex(item => item.UserID == UserID);
if (index == -1)
{
// element does not exists, do what you need
final_photolist.AddRange(temp_photolist);
}
temp_photolist.Clear();
temp_photolist.Add(p);
UserIDCount = 1;
UserID = p.UserID;
}
else
{
temp_photolist.Clear();
UserIDCount = 0;
UserID = -1;
}
}
}
}
Upvotes: 0
Reputation: 32059
Please wait! This is not the final answer! a little bit further modification is needed! modification is underway.
List<Photos> photolist = new List<Photos>()
{
new Photos() {UserID = 92, PhotoLabel = 20180729181046},
new Photos() {UserID = 92, PhotoLabel = 20180729181041},
new Photos() {UserID = 92, PhotoLabel = 20180729181037},
new Photos() {UserID = 88, PhotoLabel = 20180729174415},
new Photos() {UserID = 88, PhotoLabel = 20180729174405},
new Photos() {UserID = 04, PhotoLabel = 20180729174358},
new Photos() {UserID = 1, PhotoLabel = 20170924183847},
new Photos() {UserID = 1, PhotoLabel = 20170921231422},
new Photos() {UserID = 1, PhotoLabel = 20170920194624},
new Photos() {UserID = 32, PhotoLabel = 20170820114728},
new Photos() {UserID = 32, PhotoLabel = 20170820114725},
new Photos() {UserID = 32, PhotoLabel = 20170820114421},
new Photos() {UserID = 32, PhotoLabel = 20170820114416},
new Photos() {UserID = 1, PhotoLabel = 20170225151023},
new Photos() {UserID = 1, PhotoLabel = 20170225151000},
};
var photolist2 = photolist.GroupBy(g => g.UserID)
.Select(p => new
{
UserId = p.Key,
Count = p.Count()
})
.ToList();
var filteredPhotoList = photolist
.Join(photolist2,
photo => photo.UserID,
photo2 => photo2.UserId,
(photo, photo2) => new {UserId = photo.UserID, PhotoLabel =
photo.PhotoLabel, Count = photo2.Count})
.Where(p => p.Count > 2).Select(p => new
{
p.UserId, p.PhotoLabel
}).OrderByDescending(p => p.PhotoLabel).ThenBy(p => p.UserId).ToList();
Upvotes: 0
Reputation: 950
If I am not misunderstood the requirement, below function properly works (but it shouldn't the most efficient solution)
protected List<AnObject> aFunction(List<AnObject> sortedList)
{
//Display groups of UserIDs and PhotoLabels where UserIDs appear 3 or more times in one group (eg: rows 4 and 5 where UserID = 88 and row 6 where UserID = 04 should be eliminated since the UserID = 88 appears just twice in the group and UserID = 04 appears only once in the group).
//Display only the top most group of UserIDs and exclude any repeating UserIDs(eg: rows 7, 8 and 9 displays the UserID = 1 group.Don't display any other UserID=1 group such as rows 14,15 and 16.
int pivot = -1;
int cnt = 0;
List<AnObject> masterList = new List<AnObject>();
List<AnObject> subList = new List<AnObject>();
//List<int> Excluded = new List<int>();
foreach (AnObject r in sortedList)
{
if (pivot != r.UserID)
{
if (cnt > 2)
{
masterList.AddRange(subList);
//Excluded.Add(pivot);
}
subList.Clear();
pivot = -1;
cnt = 0;
//if (!Excluded.Contains(r.UserID))
if (!masterList.Any(x => x.UserID == r.UserID))
{
pivot = r.UserID;
}
}
subList.Add(r);
cnt++;
}
return masterList;
}
To call it for testing
protected class AnObject
{
public AnObject(int uid, string photolabel)
{
this.UserID = uid;
this.PhotoLabel = photolabel;
}
public int UserID { get; set; }
public string PhotoLabel { get; set; }
}
protected void Execute()
{
List<AnObject> sortedList = new List<AnObject>();
sortedList.Add(new AnObject(92, "anystring"));
sortedList.Add(new AnObject(92, "anystring"));
sortedList.Add(new AnObject(92, "anystring"));
sortedList.Add(new AnObject(88, "anystring"));
sortedList.Add(new AnObject(88, "anystring"));
sortedList.Add(new AnObject(4, "anystring"));
sortedList.Add(new AnObject(1, "anystringfirst"));
sortedList.Add(new AnObject(1, "anystringfirst"));
sortedList.Add(new AnObject(1, "anystringfirst"));
sortedList.Add(new AnObject(32, "anystring"));
sortedList.Add(new AnObject(32, "anystring"));
sortedList.Add(new AnObject(32, "anystring"));
sortedList.Add(new AnObject(32, "anystring"));
sortedList.Add(new AnObject(1, "anystringafter"));
sortedList.Add(new AnObject(1, "anystringafter"));
sortedList.Add(new AnObject(1, "anystringafter"));
List<AnObject> bb = aFunction(sortedList);
}
Upvotes: 1