Есть ли способ избежать дубликатов в сборщике

#c# #xamarin.forms #android-sqlite

#c# #xamarin.forms #android-sqlite

Вопрос:

Я создаю приложение для перечисления книг, которые у меня есть и которые я хочу.. это приложение имеет базу данных Sqlite. В каждой книге есть строка со столбцами ID, Author и Title. Моя проблема в том, что когда я добавляю новую книгу, я хотел дать этому пользователю возможность ввести новое имя автора или получить его из сборщика. Источник элементов сборщика поступает из столбца Authors. Моя проблема в том, что у каждого автора может быть более одной книги, имена авторов отображаются в сборщике несколько раз

Xaml

 <StackLayout Orientation="Horizontal">
    <Entry x:Name="authorName" HorizontalOptions="FillAndExpand" Text="{Binding Author}"
       Keyboard="Text" 
       StyleClass="entry"/>

    <StackLayout>
        <Button x:Name="PickAuthor" Text="..." WidthRequest="40"
        Clicked="PickAuthor_Clicked"/>
    </StackLayout>

    <Picker x:Name="ExistingAuthors"
            Title="Select Author"
            IsVisible="False"
            SelectedIndexChanged="ExistingAuthors_SelectedIndexChanged">
        <Picker.ItemDisplayBinding>
            <Binding Path="Author" />
        </Picker.ItemDisplayBinding>
    </Picker>
</StackLayout>
  

Код, лежащий в основе

 protected override async void OnAppearing()
{
    await _connection.CreateTableAsync<WishList>();
    var book = await _connection.Table<WishList>().ToListAsync();
    _book = new ObservableCollection<WishList>(book);
    base.OnAppearing();
}

private void PickAuthor_Clicked(object sender, EventArgs e)
{
    ExistingAuthors.ItemsSource = _book.Distinct().ToList();
    ExistingAuthors.Focus();
}

private void ExistingAuthors_SelectedIndexChanged(object sender, EventArgs e)
{
    authorName.Text = ExistingAuthors.Items[ExistingAuthors.SelectedIndex];
}
  

Я не хочу, чтобы сборщик вытеснял дубликаты.

Ответ №1:

Чтобы удалить дубликаты из списка, вы можете использовать Linq. Приведенный ниже метод группирует коллекцию по повторяющемуся полю и выбирает первую группу.

 private void PickAuthor_Clicked(object sender, EventArgs e)
{
    ExistingAuthors.ItemsSource = _book.GroupBy(b => b.Author)    // group by Author
                                       .Select(g => g.First())    // select first group
                                       .ToList();
    ExistingAuthors.Focus();
}
  

Это вернет список вашего типа объекта.

Ответ №2:

Если вы отображаете только список авторов, выберите Authors из _book , затем вызовите Distinct , чтобы удалить повторяющиеся имена авторов.

 private void PickAuthor_Clicked(object sender, EventArgs e)
{        
    ExistingAuthors.ItemsSource = _book.Select(x => x.Author.Trim()).Distinct().ToList();
    ExistingAuthors.Focus();
}
  

Комментарии:

1. Этот метод, похоже, не хочет работать. Сборщик все еще извлекает дубликаты. может быть, ошибка в Xamarin?

2. Я обновил ответ, включив .Trim() который удалит все пробелы. Это также не чувствительно к регистру, поэтому, если список содержит «Maverick» и «индивидуалист», в списке будут отображаться как заглавные, так и некапитализированные имена.

3. Когда я добавляю точку останова в ExistingAuthors. ItemsSource = _book. Выберите(x => x.Author). Distinct(). ToList(); это показывает мне, что Distinct работает..

4. Как вы назначаете ExistingAuthors.ItemsSource перед нажатием кнопки?

5. при нажатии кнопки