Невозможно отсортировать и удалить дубликаты в LINQ C # - PullRequest
1 голос
/ 04 апреля 2019

В настоящее время я хочу отсортировать список объектов в LINQ, где мне нужно отсортировать и удалить дубликаты, если они найдены. Было бы проще, если я приведу простой пример для моего сценария.

Это мой текущий список (я упростила его и отсортировала):

{
  "data": [
    {
      "userActivityId": 17,
      "deviceId": 2,
      "name": "Apple Iphone X 2013 32 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
    {
      "userActivityId": 16,
      "deviceId": 1,
      "name": "Apple Iphone X 2013 16 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
    {
      "userActivityId": 15,
      "deviceId": 1,
      "name": "Apple Iphone X 2013 16 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
    {
      "userActivityId": 14,
      "deviceId": 2,
      "name": "Apple Iphone X 2013 32 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
  ]
}

Ожидаемый результат

Что я действительно хотел:

{
  "data": [
    {
      "userActivityId": 17,
      "deviceId": 2,
      "name": "Apple Iphone X 2013 32 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
    {
      "userActivityId": 16,
      "deviceId": 1,
      "name": "Apple Iphone X 2013 16 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
  ]
}

Здесь мы можем видеть, что userActivityId 15 и 14 удалены, потому что name уже существовал там.

Таким образом, мы можем отсортировать уникальные с помощью name.

Что я пробовал

Первая попытка

Это оригинальный код для функции сортировки.

var data = new leapserverdbContext().TbUserActivity
            .OrderByDescending(id => id.UserActivityId)
            .Select(sel => new
            {
                sel.UserActivityId,
                sel.TbDevice.DeviceId,
                Name = sel.TbDevice.TbDeviceBrand.Name + " " + sel.TbDevice.Name +
                    " " + sel.TbDevice.TbDeviceYear.Year + " " + sel.TbDevice.TbDeviceSize.Size,
                    sel.TbDevice.IconResource                             
            })
            .ToList();

Вторая попытка

Я пытаюсь поставить Distinct(), но он не будет работать, потому что есть userActivityId, и он уникален (потому что увеличивается).

Третья попытка

Я пытаюсь удалить userActivityId, чтобы избежать его рассмотрения во время Distinct(), но тогда мои данные не будут отсортированы. Потому что сортировка зависит на userActivityId.

Четвертая попытка

Я пытался использовать GroupBy (x => x.Name), поэтому разделите фокус на основе уникального имени. Но просто начните делить их на массив, как указано ниже:

{
  "data": [
    [
      {
        "userActivityId": 16,
        "deviceId": 1,
        "name": "Apple Iphone X 2013 16 GB",
        "iconResource": "phone_apple_iphone_x.jpg"
      },
      {
        "userActivityId": 15,
        "deviceId": 1,
        "name": "Apple Iphone X 2013 16 GB",
        "iconResource": "phone_apple_iphone_x.jpg"
      }     
    ],
    [
      {
        "userActivityId": 17,
        "deviceId": 2,
        "name": "Apple Iphone X 2013 32 GB",
        "iconResource": "phone_apple_iphone_x.jpg"
      },
      {
        "userActivityId": 14,
        "deviceId": 2,
        "name": "Apple Iphone X 2013 32 GB",
        "iconResource": "phone_apple_iphone_x.jpg"
      }

    ]
  ]
}

Теперь он отсортирован и разделен на основе их уникального name. Но макет совершенно другой.

Что, на мой взгляд, могло бы сделать, это получить первый массив (так как он самый последний), но как мне объединить и получить Expected Result (см. Выше).

Есть ли способ решить эту мою маленькую проблему?

Ответы [ 2 ]

3 голосов
/ 04 апреля 2019

Помимо использования EqualityComparer, как ранее предлагалось, вы также можете просто сгруппировать свой результат по имени-свойству, поскольку в этом случае вы используете анонимный тип.

var data = new leapserverdbContext().TbUserActivity
        .OrderByDescending(id => id.UserActivityId)
        .Select(sel => new
        {
            sel.UserActivityId,
            sel.TbDevice.DeviceId,
            Name = sel.TbDevice.TbDeviceBrand.Name + " " + sel.TbDevice.Name +
                " " + sel.TbDevice.TbDeviceYear.Year + " " + sel.TbDevice.TbDeviceSize.Size,
            sel.TbDevice.IconResource
        })
        .GroupBy(x => x.Name)
        .Select(g => g.First())
        .ToList();
2 голосов
/ 04 апреля 2019

Вы можете создать Equal Comparer:

    public class ActivityComparer : IEqualityComparer<TbUserActivity>
    {
        public bool Equals(TbUserActivity x, TbUserActivity y)
        {
            if (x == null && y == null)
                return true;
            else if (x == null || y == null)
                return false;
            return x.name == y.name 
        }

        public int GetHashCode(TbUserActivity obj)
        {
            return obj.userActivityId;
        }
    }

А потом просто:

result.Distinct(new ActivityComparer());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...