2011年10月14日 星期五

透過LINQ取得不重複的隨機數值

日前在專案中有需要從題庫中隨機挑選題目的需求,加上最近在MSDN論壇看到有人在問隨機取得不重複的數值的問題,為了避免之後又不小心忘記這個方便的寫法,特別寫文章來紀錄一下。


MainPage.xaml
<UserControl 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"
        xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
        x:Class="SL_RandomWithLinq.MainPage" 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" Text="Silverlight 透過Linq取亂數範例"
                        VerticalAlignment="Center" FontSize="26.667" FontWeight="Bold" />
                <Rectangle Fill="#FF646464" Height="2" Margin="10,0" VerticalAlignment="Bottom" />
                <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="第 00000 期大樂透得獎號碼"
                        VerticalAlignment="Top" FontSize="32" FontWeight="Bold" Grid.Row="1" Margin="10,10,0,0"
                        FontStyle="Italic" Foreground="#FFFFC700">
                    <TextBlock.Effect>
                        <DropShadowEffect ShadowDepth="1" />
                    </TextBlock.Effect></TextBlock>
                <toolkit:WrapPanel x:Name="wrpNumbers" Margin="10,60,10,10" Grid.Row="1">
                    <toolkit:WrapPanel.Effect>
                        <DropShadowEffect Opacity="0.5" ShadowDepth="1" />
                    </toolkit:WrapPanel.Effect>
                </toolkit:WrapPanel>
                <Button x:Name="btnRandom" Content="重新開獎" HorizontalAlignment="Center" Grid.Row="3"
                        VerticalAlignment="Center" Margin="0,5,0,10" Padding="10,5" FontSize="16"
                        Click="btnRandom_Click" />
            </Grid>
        </Border>
    </theme:ExpressionDarkTheme>
</UserControl>


MainPage.xaml.cs

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace SL_RandomWithLinq
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            for( int i = 1 ; i <= 49 ; i++ )
            {
                this.wrpNumbers.Children.Add( new TextBlock
                                                {
                                                    Text = i.ToString( "00" ) ,
                                                    Foreground = new SolidColorBrush { Color = Colors.Gray } ,
                                                    FontSize = 32 ,
                                                    Width = 80 ,
                                                    Margin = new Thickness( 5 ) ,
                                                    TextAlignment = TextAlignment.Center ,
                                                } );
            }
        }

        private void btnRandom_Click( object sender , RoutedEventArgs e )
        {
            //重置所有號碼為灰色
            this.wrpNumbers.Children.OfType<TextBlock>().ToList().ForEach( t => t.Foreground = new SolidColorBrush { Color = Colors.Gray } );

            //將數值打亂之後透過Take方法取出前6個值
            var result = Enumerable.Range( 1 , 49 ).OrderBy( n => n * n * ( new Random() ).Next() ).Take( 6 );

            //將被挑選出來的號碼改為紅色
            result.ToList().ForEach( i => this.wrpNumbers.Children.OfType<TextBlock>().ElementAt( i - 1 ).Foreground = new SolidColorBrush { Color = Colors.Red } );
        }


    }
}




原始文章出自於此

2 則留言:

  1. 關於亂數,推薦黑暗大的文章:
    http://blog.darkthread.net/post-2010-09-09-random-feature.aspx

    回覆刪除
  2. 感謝你的建議~我會去參考紀錄一下~XD

    回覆刪除