在還沒有LINQ的時代,要比對兩個集合間的交集、聯集、差集關係的時候,通常得透過迴圈來實作,不過,如果改用LINQ,那就又是只要一行就可以解決啦!!
這篇文章就簡單的利用LINQ提供的Enumerable.Intetsect()方法和Enumerable.Except()方法來玩個簡單的小Demo~
在還沒有LINQ的時代,要比對兩個集合間的交集、聯集、差集關係的時候,通常得透過迴圈來實作,不過,如果改用LINQ,那就又是只要一行就可以解決啦!!
這篇文章就簡單的利用LINQ提供的Enumerable.Intetsect()方法和Enumerable.Except()方法來玩個簡單的小Demo~
直接看看這簡單到不行的範例:
再來看看程式碼:
<UserControl x:Name="userControl" x:Class="SL_CompareCollections.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:theme="clr-namespace:System.Windows.Controls.Theming;assembly=System.Windows.Controls.Theming.ExpressionDark"
mc:Ignorable="d" d:DesignHeight="600" d:DesignWidth="800">
<theme:ExpressionDarkTheme Background="{x:Null}" Foreground="#FF646464">
<Border BorderThickness="2" CornerRadius="10" Margin="10" Background="White" BorderBrush="#FF646464">
<Border.Effect>
<DropShadowEffect />
</Border.Effect>
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Center" FontSize="26.667"
FontWeight="Bold" Text="Silverlight 集合比對範例" />
<Rectangle Fill="#FF646464" Height="2" Margin="10,0" VerticalAlignment="Bottom" />
<Grid Grid.Row="1" Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="0.912*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="集合A" VerticalAlignment="Center"
FontWeight="Bold" FontSize="18.667" />
<TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="集合B" VerticalAlignment="Center"
Grid.Column="1" FontWeight="Bold" FontSize="18.667" />
<ListBox x:Name="lstCollectionA" Grid.Row="1" Margin="5,0" FontSize="21.333" IsEnabled="False" />
<ListBox x:Name="lstCollectionB" Grid.Row="1" Grid.Column="1" Margin="5,0" FontSize="21.333"
IsEnabled="False" />
</Grid>
<StackPanel Orientation="Horizontal" Grid.Row="3" VerticalAlignment="Center"
HorizontalAlignment="Center">
<Button x:Name="btnBoth" Content="兩者皆有" HorizontalAlignment="Center" VerticalAlignment="Center"
Margin="5" Padding="10,5" FontSize="13.333" Click="btnBoth_Click" />
<Button x:Name="btnOnlyA" Content="A有B沒有" HorizontalAlignment="Center" VerticalAlignment="Center"
Margin="5" Padding="10,5" FontSize="13.333" Click="btnOnlyA_Click" />
<Button x:Name="btnOnlyB" Content="B有A沒有" HorizontalAlignment="Center" VerticalAlignment="Center"
Margin="5" Padding="10,5" FontSize="13.333" Click="btnOnlyB_Click" />
</StackPanel>
</Grid>
</Border>
</theme:ExpressionDarkTheme>
</UserControl>
CodeBehind的部份如下:
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Media;
namespace SL_CompareCollections
{
public partial class MainPage : UserControl
{
private List<string> _collectionA = new List<string> { "2" , "Ouch" , "Visual Studio" , "Wei" , "Mango" , "WP7" , "3" , "Silverlight" , "RIA" };
private List<string> _collectionB = new List<string> { "Mango" , "3" , "Windows" , "Ouch" , "WPF" , "RIA" , "Metro UI" , "Yuan" , "4" };
public MainPage()
{
InitializeComponent();
lstCollectionA.ItemsSource = _collectionA;
lstCollectionB.ItemsSource = _collectionB;
}
private void ResetListBoxes()
{
_collectionA.ForEach
( item =>
{
( lstCollectionA.ItemContainerGenerator.ContainerFromItem( item ) as ListBoxItem ).Foreground = new SolidColorBrush( Colors.White );
}
);
_collectionB.ForEach
( item =>
{
( lstCollectionB.ItemContainerGenerator.ContainerFromItem( item ) as ListBoxItem ).Foreground = new SolidColorBrush( Colors.White );
}
);
}
private void btnBoth_Click( object sender , System.Windows.RoutedEventArgs e )
{
ResetListBoxes();
//也可以這樣寫
//List<string> result = _collectionA.Where( item => _collectionB.Contains( item ) ).ToList();
List<string> result = _collectionA.Intersect( _collectionB ).ToList();
result.ForEach
( item =>
{
( lstCollectionA.ItemContainerGenerator.ContainerFromItem( item ) as ListBoxItem ).Foreground = new SolidColorBrush( Colors.Red );
( lstCollectionB.ItemContainerGenerator.ContainerFromItem( item ) as ListBoxItem ).Foreground = new SolidColorBrush( Colors.Red );
}
);
}
private void btnOnlyA_Click( object sender , System.Windows.RoutedEventArgs e )
{
ResetListBoxes();
//也可以這樣寫
//List<string> result = _collectionA.Where( item => _collectionB.Contains( item ) == false ).ToList();
List<string> result = _collectionA.Except( _collectionB ).ToList();
result.ForEach
( item =>
{
( lstCollectionA.ItemContainerGenerator.ContainerFromItem( item ) as ListBoxItem ).Foreground = new SolidColorBrush( Colors.Red );
}
);
}
private void btnOnlyB_Click( object sender , System.Windows.RoutedEventArgs e )
{
ResetListBoxes();
//也可以這樣寫
//List<string> result = _collectionB.Where( item => _collectionA.Contains( item ) == false ).ToList();
List<string> result = _collectionB.Except( _collectionA ).ToList();
result.ForEach
( item =>
{
( lstCollectionB.ItemContainerGenerator.ContainerFromItem( item ) as ListBoxItem ).Foreground = new SolidColorBrush( Colors.Red );
}
);
}
}
}
這個範例只是透過LINQ實作的簡單範例,LINQ的威力可不只這樣而已,像是資料的篩選、分頁顯示等等,也都可以透過LINQ來實作;而且,LINQ這個方便的語法出現至今也好幾年了,還不習慣用它的朋友們可以考慮好好學一下囉!!
最後,少不了的專案原始檔,請自行取用: