接下來就讓我們看看到底這幾種方法怎麼使用囉!
有一些時候需要去尋找資料集中特定的資料內容,
但是資料一旦很多的時候,通常都是使用迴圈來一筆一筆確認,
在某些時候迴圈是很好用的東西,但寫作上不那麼便利跟迅速,
剛好這些條件的設計下,有除了迴圈以外的方法。
今天要介紹練習的就是這三種方法:
For Each
List.FindAll
Linq - Where Select
這三種方法的後面兩種,就是一種寫作方式便利快速的作法,
但是處理的結果也跟常用的迴圈相同。
今天居裡貓設計了一個資料格式類別,包含 No, Name, Score 的資料格式。
- public class DataClass
- {
- public int No { get; set; }
- public string Name { get; set; }
- public int Score { get; set; }
- public DataClass(int _no, string _name, int _score)
- {
- No = _no;
- Name = _name;
- Score = _score;
- }
- }
根據這樣的資料格式,來尋找特定的成績大於某數的結果,
利用上面提到的三個方法來尋找這樣的結果。
接著就來說明一下這個練習的程式設計樣式:
介面中包含幾個元件,說明如下:
Reset Data : 根據後方 NumericUpDown 裡面的數值初始化上述說明的資料格式。
For Each : 利用 For Each 的方法,尋找成績大於 Find Score 後方 NumericUpDown 數值的數。
Find All : 利用 List.FindAll 的方法,尋找成績大於 Find Score 後面 NumericUpDown 數值的數。
Linq Select : 利用 Linq 中 Where 和 Select 的方法,尋找成績大於 Find Score 後面 NumericUpDown 數值的數。
Original Data : 是這次資料的總資料內容。
Find Data : 是尋找成功的資料內容。
介紹完介面之後,讓我們來看一下尋找的結果吧!
橘色框線內為 For Each 的搜尋結果,花費時間跟尋找的筆數。
綠色框線內為 Find All 的搜尋結果,花費時間跟尋找的筆數。
紫色框線內為 Linq Select 的搜尋結果,花費時間跟尋找的筆數。
針對花費的時間來看,便利的寫法並不一定會得到更好的時間花費,
在相同搜尋結果下,如果在需要更快速的處理速度,更少的花費時間,
For Each 的作法不見得不好,
但不要求快速的處理始間下,另外兩種方法的便利寫法、較簡單的程式碼,
或許會讓閱讀的狀態更為良好。
接下來就來看看程式碼吧!
本次範例的介面設計皆由程式碼產生,
所以以下程式碼中會看到介面設計的方法內容,請見諒。
-------------------------------程式碼分割線------------------------------------------------------------
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.Diagnostics;
- namespace TestFindListData
- {
- public partial class MainForm : Form
- {
- #region Fields
- private Button _btnUITest;
- private Button[] _btnFunction;
- private Label[] _lblFunctionCost;
- private NumericUpDown[] _nudDataNumber;
- private ListBox[] _lsbDataInfo;
- private List<DataClass> _lsData;
- private List<DataClass> _lsFindScore;
- private Random _rndScore;
- private Stopwatch _sw;
- #endregion // Fields
- #region Construct
- public MainForm()
- {
- InitializeComponent();
- Initial();
- }
- #endregion // Construct
- #region Event
- private void btnUITest_Click(object sender, EventArgs e)
- {
- this.Controls.Clear();
- Initial();
- }
- private void btnFunction_Click(object sender, EventArgs e)
- {
- Button _tmpBtn = (Button)sender;
- switch (_tmpBtn.Name)
- {
- case "btnFunctionData":
- InitialTestData(Convert.ToInt32(_nudDataNumber.First(x=>x.Name == "nudDataCount").Value));
- break;
- case "btnFunctionFor":
- FunctionForEach(_lsData, Convert.ToInt32(_nudDataNumber.First(x => x.Name == "nudScore").Value));
- break;
- case "btnFunctionFind":
- FunctionFindAll(_lsData, Convert.ToInt32(_nudDataNumber.First(x => x.Name == "nudScore").Value));
- break;
- case "btnFunctionLinq":
- FunctionLinq(_lsData, Convert.ToInt32(_nudDataNumber.First(x => x.Name == "nudScore").Value));
- break;
- }
- }
- #endregion // Event
- #region Function
- #region Private Function
- private void Initial()
- {
- this.Width = 640;
- this.Height = 640;
- // CreateButtonWithUI(); // This function will create UI reset function
- CreateButtonWithFunction(4);
- CreateLabelWithFunctionCost(6);
- CreateNumbericUpDown(2);
- CreateListbox(2);
- InitialTestData(10);
- }
- private void InitialTestData(int _total)
- {
- if (_lsData == null)
- {
- _lsData = new List<DataClass>();
- }
- if (_lsData.Count > 0)
- {
- _lsData.Clear();
- _lsData = new List<DataClass>();
- }
- _rndScore = new Random();
- for (int i = 0; i<_total;i++)
- {
- _lsData.Add(new DataClass(i, Convert.ToString((char)(i+65)), _rndScore.Next(0, 100)));
- }
- if (_lsbDataInfo.First(x => x.Name == "lsbOriginalData").Items.Count > 0) { _lsbDataInfo.First(x => x.Name == "lsbOriginalData").Items.Clear(); }
- foreach (var tmp in _lsData)
- {
- _lsbDataInfo.First(x => x.Name == "lsbOriginalData").Items.Add("No: " + tmp.No.ToString() + " Name: " + tmp.Name + " Score: " + tmp.Score);
- }
- }
- private void FunctionForEach(List<DataClass> _ls, int _findScore)
- {
- if (_ls == null) { MessageBox.Show("The data list is null so will return FunctionForEach"); return; }
- _lsFindScore = new List<DataClass>();
- _sw = new Stopwatch();
- _sw.Reset();
- _sw.Start();
- foreach(var tmp in _ls)
- {
- if (tmp.Score > _findScore)
- {
- _lsFindScore.Add(tmp);
- }
- }
- _sw.Stop();
- _lblFunctionCost.First(x => x.Name == "lblFunctionCostFor").Text = "For Cost: " + _sw.Elapsed.TotalMilliseconds.ToString() + " ms Find count: " + _lsFindScore.Count.ToString();
- if (_lsbDataInfo.First(x => x.Name == "lsbFindData").Items.Count > 0) { _lsbDataInfo.First(x => x.Name == "lsbFindData").Items.Clear(); }
- foreach (var tmp in _lsFindScore)
- {
- _lsbDataInfo.First(x => x.Name == "lsbFindData").Items.Add("No: " + tmp.No.ToString() + " Name: " + tmp.Name + " Score: " + tmp.Score);
- }
- }
- private void FunctionFindAll(List<DataClass> _ls, int _findScore)
- {
- if (_ls == null) { MessageBox.Show("The data list is null so will return FunctionForEach"); return; }
- _lsFindScore = new List<DataClass>();
- _sw = new Stopwatch();
- _sw.Reset();
- _sw.Start();
- _lsFindScore = _lsData.FindAll(x => x.Score > _findScore).ToList();
- _sw.Stop();
- _lblFunctionCost.First(x => x.Name == "lblFunctionCostFind").Text = "FindAll Cost: " + _sw.Elapsed.TotalMilliseconds.ToString() + " ms Find count: " + _lsFindScore.Count.ToString();
- if (_lsbDataInfo.First(x => x.Name == "lsbFindData").Items.Count > 0) { _lsbDataInfo.First(x => x.Name == "lsbFindData").Items.Clear(); }
- foreach (var tmp in _lsFindScore)
- {
- _lsbDataInfo.First(x => x.Name == "lsbFindData").Items.Add("No: " + tmp.No.ToString() + " Name: " + tmp.Name + " Score: " + tmp.Score);
- }
- }
- private void FunctionLinq(List<DataClass> _ls, int _findScore)
- {
- if (_ls == null) { MessageBox.Show("The data list is null so will return FunctionForEach"); return; }
- _lsFindScore = new List<DataClass>();
- _sw = new Stopwatch();
- _sw.Reset();
- _sw.Start();
- _lsFindScore =
- (from tmp in _lsData
- where tmp.Score > _findScore
- select tmp).ToList();
- _sw.Stop();
- _lblFunctionCost.First(x => x.Name == "lblFunctionCostLinq").Text = "LinqSelect Cost: " + _sw.Elapsed.TotalMilliseconds.ToString() + " ms Find count: " + _lsFindScore.Count.ToString();
- if (_lsbDataInfo.First(x => x.Name == "lsbFindData").Items.Count > 0) { _lsbDataInfo.First(x => x.Name == "lsbFindData").Items.Clear(); }
- foreach (var tmp in _lsFindScore)
- {
- _lsbDataInfo.First(x => x.Name == "lsbFindData").Items.Add("No: " + tmp.No.ToString() + " Name: " + tmp.Name + " Score: " + tmp.Score);
- }
- }
- #region Create UI
- private void CreateButtonWithUI()
- {
- _btnUITest = new Button();
- _btnUITest.Name = "btnUITest";
- _btnUITest.Text = "UI Test";
- _btnUITest.Location = new Point(this.Width - 100, this.Height - 100);
- _btnUITest.Click += btnUITest_Click;
- this.Controls.Add(_btnUITest);
- }
- private void CreateButtonWithFunction(int _total)
- {
- _btnFunction = new Button[_total];
- for (int i = 0; i<_total;i++)
- {
- _btnFunction[i] = new Button();
- switch(i)
- {
- case 0:
- _btnFunction[i].Name = "btnFunctionData";
- _btnFunction[i].Text = "Reset Data";
- _btnFunction[i].Size = new Size(100, 20);
- _btnFunction[i].Location = new Point(20, 20);
- _btnFunction[i].Click += btnFunction_Click;
- break;
- case 1:
- _btnFunction[i].Name = "btnFunctionFor";
- _btnFunction[i].Text = "For Each";
- _btnFunction[i].Size = new Size(100, 20);
- _btnFunction[i].Location = new Point(20, 50);
- _btnFunction[i].Click += btnFunction_Click;
- break;
- case 2:
- _btnFunction[i].Name = "btnFunctionFind";
- _btnFunction[i].Text = "Find All";
- _btnFunction[i].Size = new Size(100, 20);
- _btnFunction[i].Location = new Point(20, 80);
- _btnFunction[i].Click += btnFunction_Click;
- break;
- case 3:
- _btnFunction[i].Name = "btnFunctionLinq";
- _btnFunction[i].Text = "Linq Select";
- _btnFunction[i].Size = new Size(100, 20);
- _btnFunction[i].Location = new Point(20, 110);
- _btnFunction[i].Click += btnFunction_Click;
- break;
- }
- this.Controls.Add(_btnFunction[i]);
- }
- }
- private void CreateLabelWithFunctionCost(int _total)
- {
- _lblFunctionCost = new Label[_total];
- for (int i = 0; i<_total;i++)
- {
- _lblFunctionCost[i] = new Label();
- switch(i)
- {
- case 0:
- _lblFunctionCost[i].Name = "lblFunctionCostFor";
- _lblFunctionCost[i].Text = "For Cost: ";
- _lblFunctionCost[i].Location = new Point(140, 50);
- _lblFunctionCost[i].Size = new Size(300, 20);
- break;
- case 1:
- _lblFunctionCost[i].Name = "lblFunctionCostFind";
- _lblFunctionCost[i].Text = "FindAll Cost: ";
- _lblFunctionCost[i].Location = new Point(140, 80);
- _lblFunctionCost[i].Size = new Size(300, 20);
- break;
- case 2:
- _lblFunctionCost[i].Name = "lblFunctionCostLinq";
- _lblFunctionCost[i].Text = "LinqSelect Cost: ";
- _lblFunctionCost[i].Location = new Point(140, 110);
- _lblFunctionCost[i].Size = new Size(300, 20);
- break;
- case 3:
- _lblFunctionCost[i].Name = "lblOriginalData";
- _lblFunctionCost[i].Text = "Original Data: ";
- _lblFunctionCost[i].Location = new Point(20, 140);
- _lblFunctionCost[i].Size = new Size(200, 20);
- break;
- case 4:
- _lblFunctionCost[i].Name = "lblFindData";
- _lblFunctionCost[i].Text = "Find Data: ";
- _lblFunctionCost[i].Location = new Point(310, 140);
- _lblFunctionCost[i].Size = new Size(200, 20);
- break;
- case 5:
- _lblFunctionCost[i].Name = "lblScore";
- _lblFunctionCost[i].Text = "Find Score: ";
- _lblFunctionCost[i].Location = new Point(310, 20);
- _lblFunctionCost[i].Size = new Size(100, 20);
- break;
- }
- this.Controls.Add(_lblFunctionCost[i]);
- }
- }
- private void CreateNumbericUpDown(int _total)
- {
- _nudDataNumber = new NumericUpDown[_total];
- for (int i = 0;i<_total;i++)
- {
- _nudDataNumber[i] = new NumericUpDown();
- switch (i)
- {
- case 0:
- _nudDataNumber[i].Name = "nudDataCount";
- _nudDataNumber[i].Value = 10;
- _nudDataNumber[i].Size = new Size(50, 20);
- _nudDataNumber[i].Location = new Point(140, 20);
- _nudDataNumber[i].Minimum = 0;
- _nudDataNumber[i].Maximum = 9999;
- _nudDataNumber[i].Increment = 1;
- break;
- case 1:
- _nudDataNumber[i].Name = "nudScore";
- _nudDataNumber[i].Value = 10;
- _nudDataNumber[i].Size = new Size(50, 20);
- _nudDataNumber[i].Location = new Point(410, 20);
- _nudDataNumber[i].Minimum = 0;
- _nudDataNumber[i].Maximum = 100;
- _nudDataNumber[i].Increment = 1;
- break;
- }
- this.Controls.Add(_nudDataNumber[i]);
- }
- }
- private void CreateListbox(int _total)
- {
- _lsbDataInfo = new ListBox[_total];
- for (int i = 0; i<_total;i++)
- {
- _lsbDataInfo[i] = new ListBox();
- switch(i)
- {
- case 0:
- _lsbDataInfo[i].Name = "lsbOriginalData";
- _lsbDataInfo[i].Location = new Point(20, 160);
- _lsbDataInfo[i].Size = new Size(250, 400);
- break;
- case 1:
- _lsbDataInfo[i].Name = "lsbFindData";
- _lsbDataInfo[i].Location = new Point(310, 160);
- _lsbDataInfo[i].Size = new Size(250, 400);
- break;
- }
- this.Controls.Add(_lsbDataInfo[i]);
- }
- }
- #endregion // Create UI
- #endregion Private Function
- #endregion // Function
- }
- public class DataClass
- {
- public int No { get; set; }
- public string Name { get; set; }
- public int Score { get; set; }
- public DataClass(int _no, string _name, int _score)
- {
- No = _no;
- Name = _name;
- Score = _score;
- }
- }
- }
沒有留言:
張貼留言