[C#][Silverlight] 透過LINQ實作兩集合間的交集與差集比對

  • 5291
  • 0
  • C#
  • 2013-07-15

在還沒有LINQ的時代,要比對兩個集合間的交集、聯集、差集關係的時候,通常得透過迴圈來實作,不過,如果改用LINQ,那就又是只要一行就可以解決啦!!
這篇文章就簡單的利用LINQ提供的Enumerable.Intetsect()方法和Enumerable.Except()方法來玩個簡單的小Demo~

 

在還沒有LINQ的時代,要比對兩個集合間的交集、聯集、差集關係的時候,通常得透過迴圈來實作,不過,如果改用LINQ,那就又是只要一行就可以解決啦!!

這篇文章就簡單的利用LINQ提供的Enumerable.Intetsect()方法和Enumerable.Except()方法來玩個簡單的小Demo~

 

直接看看這簡單到不行的範例:

 

再來看看程式碼:

MainPage.xaml
<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的部份如下:

MainPage.xaml.cs
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這個方便的語法出現至今也好幾年了,還不習慣用它的朋友們可以考慮好好學一下囉!!

 

最後,少不了的專案原始檔,請自行取用: