Как отфильтровать список? - PullRequest
0 голосов
/ 16 ноября 2009

Это метод, который должен удалять уже назначенных пользователей из списка. и сохранить неназначенные в списке. В GuidList добавлен userId к нему по нажатию кнопки. ProfileList используется для заполнения gridView.

Вот код:

private VList<VW_profiles> FilterAssigned(VList<VW_profiles> profileList)
{
    VList<VW_profiles> sortedList = new VList<VW_profiles>();
    foreach(VW_profiles profile in profileList)
    {
        if(GuidList.Count > 0)
        {
            foreach(Guid userId in GuidList)
            {
                if(profile.UserId != userId)
                {
                    sortedList.Add(profile)
                }
            }
        }       
        else
        {
            sortedList = profileList;
        }
    }
    return sortedList;
}

Теперь вот моя проблема. Кажется, все работает хорошо до все элементы в profileList также были добавлен в GuidList. Тогда вместо того, чтобы отрицать два идентификатора Guid, мы начинаем добавлять всех снова. Есть ли у кого-нибудь какие-либо предложения о том, как сделать это более эффективным способом и избежать добавления, как только мы вынули все.

Спасибо!

Ответы [ 2 ]

6 голосов
/ 16 ноября 2009

Если VList<T> является List<T>, то вы можете сделать это:

profileList.RemoveAll(profile => GuidList.Contains(profile.UserId));

Если производительность является проблемой, и для удаления есть МНОЖЕСТВО GuidsList, вы можете сделать GuidList HashSet<Guid>.

Редактировать На основе комментариев: Если вы не хотите изменять исходный список, сделайте следующее:

var filtered = new VList<VW_profiles>(
    profileList.Where(profile => !GuidList.Contains(profile.UserId)));

Редактировать Если вы не используете List<T>, вот метод, который вы можете использовать в списках с изменяемым размером, реализующий IList<T>, и метод, который вы можете использовать в массивах (T[]). Удаляя только элементы из конца списка, алгоритм O (n²) будет иметь значение O (n) для большинства реализаций IList<T>.

.
public static void RemoveAll<T>(this IList<T> list, Predicate<T> match)
{
    if (list == null)
        throw new ArgumentNullException("list");
    if (match == null)
        throw new ArgumentNullException("match");
    if (list is T[])
        throw new ArgumentException("Arrays cannot be resized.");

    // early out
    if (list.Count == 0)
        return;

    // List<T> provides special handling
    List<T> genericList = list as List<T>;
    if (genericList != null)
    {
        genericList.RemoveAll(match);
        return;
    }

    int targetIndex = 0;
    for (int i = 0; i < list.Count; i++)
    {
        if (!match(list[i]) && targetIndex != i)
        {
            list[targetIndex] = list[i];
            targetIndex++;
        }
    }

    // Unfortunately IList<T> doesn't have RemoveRange either
    for (int i = list.Count - 1; i >= targetIndex; i--)
    {
        list.RemoveAt(i);
    }
}

public static void RemoveAll<T>(ref T[] array, Predicate<T> match)
{
    if (array == null)
        throw new ArgumentNullException("array");
    if (match == null)
        throw new ArgumentNullException("match");

    int targetIndex = 0;
    for (int i = 0; i < array.Length; i++)
    {
        if (!match(array[i]) && targetIndex != i)
        {
            array[targetIndex] = array[i];
            targetIndex++;
        }
    }

    if (targetIndex != array.Length)
    {
        Array.Resize(ref array, targetIndex);
    }
}
2 голосов
/ 16 ноября 2009

Ваша проблема в этом коде:

foreach(Guid userId in GuidList)
{
    if(profile.UserId != userId)
    {
        sortedList.Add(profile)
    }
}

Это должно быть больше похоже на:

bool inList = false;
foreach(Guid userId in GuidList)
{
    if(profile.UserId == userId)
    {
        inList = true;
    }
}
if (!inList)
    sortedList.Add(profile)

или более LINQ-стиль:

bool inList = GuidList.Any(x => x == profile.UserId);
if (!inList)
    sortedList.Add(profile)

Ваш текущий код больше похож на:

GuidList.Where(x => x != profile.UserId)
        .Foreach(x => sortedList.Add(x));

что я думаю не то, что вы хотите:)

...