简体   繁体   中英

Filtering an old list to a new list C#

I want to compare 2 lists.

1 list has some GlueLines these are objects with 2 properties: StartPosition , EndPosition (both PointF )

List 2 is empty and needs to be filled with new lines.

I only want to add a new GlueLine when there is no other object in the DrawLines list with that specific StartPosition.Y value.

Below you can find the code:

List<GlueLine> SortedList;
List<GlueLine> DrawLines = new List<GlueLine>();

SortedList = a_listGlueLines.OrderBy(o => Math.Round(o.StartPosition.X, 2)).ToList();

for(int i =0; i <SortedList.Count; i++)
{
    if(DrawLines.Count < 0)
    {
         for(int j = 0; j < DrawLines.Count; j++)
         {
            if(SortedList[i].StartPosition.Y != DrawLines[...].StartPosition.Y) // ... needs to be ALL of the objects in that list
            {
              DrawLines.Add(SortedList[i]);
            }
         }
    }
    else
    {
          DrawLines.Add(SortedList[i]);
    }
}

Or is there some other way to compare 1 object of 1 list to all the objects in the other list?

Use MoreLINQ , which has a DistinctBy method.

IEnumerable<GlueLines> distinctLinesByY = lines.DistinctBy(line => line.Y);

If you don't want to depend on the library, just implement the one method:

public static class EnumerableExtensions
{
    public static IEnumerable<TSource> DistinctBy<TSource, TKey>(IEnumerable<TSource> source,
                                                                 Func<TSource, TKey> keySelector)
    {
        var knownKeys = new HashSet<TKey>();
        return source.Where(element => knownKeys.Add(keySelector(element)));
    }
}

To do it efficiently, I would use a Dictionary<Single,GlueLine> with the key being the Y coordinate. ie change

List<GlueLine> DrawLines = new List<GlueLine>(); 

to

Dictionary<Single,GlueLine> DrawLines = new Dictionary<Single,GlueLine>();

You can replace the inside of your loop with

if (!DrawLines.ContainsKey(SortedList[i].StartPosition.Y))
    DrawLines.Add(SortedList[i].StartPosition.Y, SortedList[i])

If speed isn't an issue then you can use a linq query to select the distinct Y coordinates into a list, then select from each of those, the First matching GlueLine. This isn't very efficient, but you might feel it is easier to code/read.

i see you want to do it from scratch... here is a way to do it

List<GlueLine> SortedList;
List<GlueLine> DrawLines = new List<GlueLine>();
SortedList = a_listGlueLines.OrderBy(o => Math.Round(o.StartPosition.X,2)).ToList();

foreach(GlueLine current in SortedList){
    Boolean found = false;
    foreach(GlueLine anyLine in DrawLines){
        if(current.StartPosition.Y == anyLine.StartPosition.Y){
            found = true;
            break;
        }
    }
    if(!found){
        DrawLines.Add(current);
    }
}

if you want a more elegant way you can go with Kvam solution

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM