Bạn đang xem bài viết Vòng Lặp Foreach Trong Lập Trình C# Cơ Bản được cập nhật mới nhất trên website Channuoithuy.edu.vn. Hy vọng những thông tin mà chúng tôi đã chia sẻ là hữu ích với bạn. Nếu nội dung hay, ý nghĩa bạn hãy chia sẻ với bạn bè của mình và luôn theo dõi, ủng hộ chúng tôi để cập nhật những thông tin mới nhất.
Dẫn nhập
Ở các bài học trước, chúng ta đã cùng nhau tìm hiểu về MẢNG NHIỀU CHIỀU TRONG C#. Hôm nay chúng ta sẽ cùng tìm hiểu về cấu trúc lặp foreach trong C#.
Nội dung
Để đọc hiểu bài này tốt nhất các bạn nên có kiến thức cơ bản về các phần:
Trong bài học này, chúng ta sẽ cùng tìm hiểu các vấn đề:
Cú pháp và nguyên tắc hoạt động của
foreach
trong C#
Sử dụng
foreach
trong C#
So sánh for và
foreach
trong C#
Cú pháp và nguyên tắc hoạt động của foreach trong C#
Cấu trúc lặp foreach cho phép chúng ta duyệt 1 mảng hoặc 1 tập hợp (sẽ được trình bày trong bài TỔNG QUAN VỀ COLLECTION TRONG C#).
Một số đặc trưng của foreach:
Foreach không duyệt mảng hoặc tập hợp thông qua chỉ số phần tử như cấu trúc lặp for.
Foreach duyệt tuần tự các phần tử trong mảng hoặc tập hợp.
Foreach chỉ dùng để duyệt mảng hoặc tập hợp ngoài ra không thể làm gì khác.
Cú pháp
{
}
Trong đó:
Các từ khoá foreach, in là từ khoá bắt buộc.
Nguyên tắc hoạt động
Foreach cũng có nguyên tắc hoạt động tương tự như các cấu trúc lặp khác cụ thể như sau:
Ở vòng lặp đầu tiên sẽ gán giá trị của phần tử đầu tiên trong mảng vào
biến tạm
.
Thực hiện khối lệnh bên trong vòng lặp
foreach
.
Qua mỗi vòng lặp tiếp theo sẽ thực hiện kiểm tra xem đã duyệt hết mảng hoặc tập hợp chưa. Nếu chưa thì tiếp gán giá trị của phần tử hiện tại vào
biến tạm
và tiếp tục thực hiện khối lệnh bên trong.
Nếu đã duyệt qua hết các phần tử thì vòng lặp sẽ kết thúc.
Qua nguyên tắc hoạt động trên ta có thể thấy:
Biến tạm
trong vòng lặp
foreach
sẽ tương đương với phần tử i trong cách duyệt của vòng lặp
for
(đã trình bày trong bài CẤU TRÚC VÒNG LẶP FOR TRONG C#).
Qua mỗi bước lặp ta chỉ có thể thao tác với giá trị của phần tử đang xét mà không thể tương tác với các phần tử đứng trước nó hay đứng sau nó (trong CẤU TRÚC VÒNG LẶP FOR TRONG C# thì hoàn toàn được).
Bằng cách duyệt của
foreach
ta không thể thay đổi giá trị của các phần tử vì lúc này giá trị của nó đã được sao chép ra một 1 biến tạm và ta chỉ có thể thao tác với
biến tạm
.
Thậm chí việc thay đổi
giá trị
của
biến tạm
cũng không được phép. Nếu ta cố làm điều đó thì sẽ gặp lỗi sau:
Sử dụng foreach trong C#
Trong C#, có những danh sách, tập hợp mà ta không thể truy xuất đến các phần tử của nó thông qua chỉ số phần tử được (ví dụ như kiểu List – sẽ được trình bày trong bài LIST TRONG C# hoặc các collection, generic – sẽ được trình bày trong bài COLLECTION TRONG C# và bài GENERIC TRONG C#).
Trong trường hợp như vậy, để duyệt các danh sách, tập hợp có tính chất như trên thì foreach là lựa chọn tốt nhất.
Chúng ta sẽ tìm hiểu sức mạnh của foreach qua các bài học sau. Còn trong bài học này mình chỉ ví dụ đơn giản để các bạn có thể nắm cú pháp cũng như cách sử dụng foreach.
Xét chương trình sau:
/* * Khai báo mảng 1 chiều IntArray và khởi tạo giá trị. * Các bạn có thể xem lại cú pháp này ở bài Mảng 1 chiều trong C# * Khai báo 1 biến Sum để chứa giá trị tổng các phần tử trong mảng IntArray. */ int[] IntArray = { 1, 5, 2, 4, 6 }; int Sum = 0; /* * Sử dụng foreach để duyệt mảng và in giá trị của các phần tử trong mảng. * Đồng thời tận dụng vòng lặp để tính tổng các phần tử trong mảng. */ foreach (int item in IntArray) { Console.Write("t" + item); Sum += item; } Console.WriteLine("n Sum = " + Sum);
Có lẽ chúng ta đã không mấy xa lạ với đoạn chương trình trên. Đoạn chương trình trên sẽ duyệt mảng để in ra các giá trị của mảng và tính tổng các phần tử trong mảng.
Nhưng thay vì sử dụng for thì mình sử dụng foreach để các bạn có thể thấy được sự tương đồng giữa các thành phần trong cấu trúc foreach và CẤU TRÚC VÒNG LẶP FOR TRONG C#.
Kết quả khi chạy đoạn chương trình trên:
Ví dụ thứ 2: ta thử sử dụng foreach để duyệt mảng jagged
/* * Khai báo 1 mảng jagged tên là JaggedArray và khởi tạo giá trị. * Các bạn có thể xem lại cú pháp khai báo này ở bài Mảng nhiều chiều trong C#. */ int[][] JaggedArray = { new int[] { 1, 2, 3 }, new int[] { 5, 2, 4, 1, 6}, new int[] { 7, 3, 4, 2, 1, 5, 9, 8} }; /* * Tương tự như dùng for, ta cũng dùng 2 vòng foreach lồng vào nhau để duyệt mảng. */ foreach (int[] Element in JaggedArray) { foreach (int item in Element) { Console.Write(item + " "); } Console.WriteLine(); }
Ta có thể thấy cách duyệt foreach ngắn gọn hơn nhiều so với cách duyệt bằng vòng lặp for thông thường.
Ta cũng chả quan tâm đến việc phải xử lý độ dài mảng hay chỉ số phần tử để truy xuất 1 phần tử nào đó.
Kết quả khi chạy đoạn chương trình trên:
So sánh for và foreach trong C#
Foreach mang trong mình một số ưu điểm như:
Câu lệnh ngắn gọn, sẽ sử dụng.
Rất có ích khi duyệt danh sách, tập hợp mà không thể truy xuất thông qua chỉ số phần tử.
Duyệt các danh sách, tập hợp có số phần tử không xác định hoặc số phần tử thay đổi liên tục.
Tiêu chí
For
Foreach
Khả năng truy xuất phần tử
Truy xuất ngẫu nhiên (có thể gọi bất kỳ phần tử nào trong mảng để sử dụng)
Truy xuất tuần tự (chỉ sử dụng được giá trị phần tử đang xét)
Thay đổi được giá trị của các phần tử
Có
Không
Duyệt mảng, tập hợp khi không biết được số phần tử của mảng, tập hợp
Không
Có
Hiệu suất (tốc độ xử lý) (*)
Đối với mảng, danh sách hoặc tập hợp có khả năng truy xuất ngẫu nhiên thì for sẽ chiếm ưu thế
Đối với mảng, danh sách hoặc tập hợp không có khả năng truy xuất ngẫu nhiên thì foreach chiếm ưu thế
(*) Nhìn chung hiệu suất của for và foreach còn phụ thuộc vào cấu trúc dữ liệu đang xét cho nên việc so sánh này chỉ mang tính chất tham khảo.
Đầu tiên là mảng 1 chiều:
/* Kiểm tra tốc độ của for */ /* * Sử dụng 1 cái đồng hồ để đo thời gian chạy của 2 vòng lặp for và foreach * Ở đây mình chỉ kiểm tra tốc độ chứ không tập trung giải thích cú pháp * Các bạn có thể tìm hiểu thêm. */ Stopwatch start = new Stopwatch(); start.Start(); int[] IntArray = new int[Int32.MaxValue / 100]; int s = 0; int Length = IntArray.Length; for (int i = 0; i < Length; i++) { s += IntArray[i]; } start.Stop(); Console.WriteLine(" Thoi gian chay cua for: {0} giay {1} mili giay", start.Elapsed.Seconds, start.Elapsed.Milliseconds); /* Kiểm tra tốc độ của foreach */ Stopwatch start2 = new Stopwatch(); start2.Start(); int[] IntArray2 = new int[Int32.MaxValue / 100]; int s2 = 0; foreach (int item in IntArray2) { s2 += item; } start2.Stop(); Console.WriteLine(" Thoi gian chay cua foreach: {0} giay {1} mili giay", start2.Elapsed.Seconds, start2.Elapsed.Milliseconds);
Đoạn chương trình mình thực hiện:
Khai báo 1 mảng 1 chiều có 20 triệu phần tử (khai báo số phần tử lớn để có thể thấy được sự chêch lệch về tốc độ)
Lần lượt dùng
for
,
foreach
để duyệt mảng đó và thực hiện 1 câu lệnh nào đó.
Cuối cùng là xuất ra thời gian thực thi của từng trường hợp dưới dạng giây và mili giây.
Kết quả khi chạy đoạn chương trình trên:
Dựa vào kết quả ta có thể thấy được sự chêch lệch nhỏ về tốc độ, nếu kiểm tra với số phần tử lớn hơn hoặc cấu trúc dữ liệu phức tạp hơn thì chêch lệch này càng lớn.
Tiếp theo là đến danh sách liên kết LinkedList:
/* * Khai báo 1 LinkedList chưa các số nguyên int và khởi tạo giá trị cho nó. */ for (int i = 0; i < 100000; i++) { list.AddLast(i); } /* Kiểm tra tốc độ của for */ Stopwatch st = new Stopwatch(); int s1 = 0, length = list.Count; st.Start(); for (int i = 0; i < length; i++) { /* * Vì LinkedList không thể truy xuất thông qua chỉ số phần tử * nên mình phải sử dụng 1 phương thức hỗ trợ làm điều này. * Và đây chính là sự hạn chế của for đối với các cấu trúc dữ liệu tương tự như danh sách liên kết này. */ s1 += list.ElementAt(i); } st.Stop(); /* Kiểm tra tốc độ của foreach */ Stopwatch st2 = new Stopwatch(); int s2 = 0; st2.Start(); foreach (int item in list) { /* * Vì foreach không quan tâm đến chỉ số phần tử nên code viết rất ngắn gọn */ s2 += item; } st2.Stop(); /* In ra giá trị tính tổng giá trị các phần tử khi duyệt bằng for và foreach để chắc chắn rằng cả 2 đều chạy đúng */ Console.WriteLine(" s1 = {0} s2 = {1}", s1, s2); Console.WriteLine(" Thoi gian chay cua for = {0} giay {1} mili giay", st.Elapsed.Seconds, st.Elapsed.Milliseconds); Console.WriteLine(" Thoi gian chay cua foreach = {0} giay {1} mini giay", st2.Elapsed.Seconds, st2.Elapsed.Milliseconds);
Chương trình mình thực hiện:
Tạo 1
LinkedList
và thêm vào 100000 phần tử.
Sau đó lần lượt dùng
for
,
foreach
duyệt
LinkedList
trên và tính tổng giá trị các phần tử trong mảng.
Cuối cùng in ra thời gian chạy của
for
,
foreach
.
Kết quả khi chạy chương trình trên là:
Dựa vào kết quả chạy ta thấy sự chênh lệch là quá lớn, rõ ràng đối với cấu trúc dữ liệu phức tạp, không hỗ trợ truy xuất thông qua chỉ số phần tử nữa thì foreach chiếm ưu thế.
Tuỳ vào từng trường hợp mà ta nên dùng for hay foreach. Không nên lạm dụng 1 thứ quá nhiều.
Kết luận
Nội dung bài này giúp các bạn nắm được:
Cú pháp của
foreach
trong C#.
Sử dụng
foreach
trong C#.
So sánh
for
và
foreach
trong C#.
Bài sau chúng ta sẽ tìm hiểu về LỚP STRING TRONG C#.
Tải xuống
Tài liệu
Nhằm phục vụ mục đích học tập Offline của cộng đồng, Kteam hỗ trợ tính năng lưu trữ nội dung bài học Vòng lặp foreach trong lập trình C# cơ bản dưới dạng file PDF trong link bên dưới.
Ngoài ra, bạn cũng có thể tìm thấy các tài liệu được đóng góp từ cộng đồng ở mục TÀI LIỆU trên thư viện Howkteam.com
Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện chúng tôi để nhận được sự hỗ trợ từ cộng đồng.
Hướng Dẫn Sử Dụng Vòng Lặp Foreach
Chia sẻ
Giới thiệu
Trong bài này chúng tôi sẽ hướng dẫn các bạn sử dụng vòng lặp foreach một cách căn bản nhất.
Vòng lặp foreach trong C# có nhiệm vụ thực thi một khối lệnh theo từng phần tử của một mảng hoặc của một tập hợp đối tượng. Khi thực thi ,vòng lặp foreach sẽ duyệt qua từng phần tử trong tập hợp đối tượng hoặc mảng.
Cú pháp của vòng lặp foreach
foreach(variable type in collection) { }Trong đó
+ variable type : Kiểu biến được sử dụng trong mảng hoặc trong tập hợp Collection + collection : Tập hợp các phần tửVí dụ sử dụng vòng lặp foreach để liệt kê các ngày trong tuần, có thể thực hiện như sau, ban đầu cần khai báo 7 ngày trong tuần vào một mảng kiểu string. Tiếp theo thực hiện duyệt vòng lặp foreach và hiển thị từng ngày thông qua hộp thoại MessageBox.
string[] days = { "Thứ 2", "Thứ 3", "Thứ 4"}; foreach (string day in days) { MessageBox.Show("Hôm nay là ngày: " + day); }
Xây dựng ứng dụng
using System; using System.Windows.Forms; namespace WindowsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } { string[] days = { "Thứ 2", "Thứ 3", "Thứ 4", "Thứ 5", "Thứ 6", "Thứ 7", "Chủ nhật" }; foreach (string day in days) { MessageBox.Show("Hiện tại là ngày : " + day); } } } }
Kết luận
Bản quyền
Nội dung trên chúng tôi được biên soạn, biên dịch từ nhiều nguồn khác nhau, đồng thời đã được viết thành chương trình chạy. chúng tôi bảo lưu mọi quyền đối với những bài viết này. Mọi hình thức sao chép đều cần phải được chúng tôi cấp phép.
Chia sẻ
Điều hướng bài viết
Các Toán Tử (Operator) Cơ Bản Trong C#
> var y = x++; > x 6 > y 5 >
Đối với phép tăng giảm trước, giá trị của của toán hạng sẽ tăng 1 đơn vị trước khi thực hiện biểu thức. Hãy xem ví dụ sau:
> var x = 5; > var y = ++x; > x 6 > y 6 0101 (số thập phân 5) AND 0011 (số thập phân 3) = 0001 (số thập phân 1) Bù/Đảo bit: ~ 0111 (số thập phân 7) = 1000 (số thập phân 8) OR nhị phân: 0101 (số thập phân 5) OR 0011 (số thập phân 3) = 0111 (số thập phân 7) XOR nhị phân: 0101 (số thập phân 5) XOR 0011 (số thập phân 3) = 0110 (số thập phân 6)Một số ví dụ về phép toán dịch bit (trên số nguyên 8 bit):
00010111 << 1 (số thập phân +23) Dịch chuyển trái 1 bit = 00101110 (số thập phân +46), tương đương với nhân 2 00010111 << 2 (số thập phân +23) Dịch sang trái 2 lần. = 01011100 (số thập phân +92), tương đương nhân với 4 (2^2) > Convert.ToString(i, 2) "10111" > var j = i << 1; > j 46 > Convert.ToString(j, 2) "101110" true true > var a = false; var b = false; > a && b false false > a < b true > a > b false > a != b true > a == b false > int z = (x > y) ? x : y; > z 20 > message "a nhỏ hơn b" > > string str = ""; > (str == "") ? "Xâu rỗng" : "Xâu không rỗng" "Xâu rỗng" > x += 1 3 > x *= 2 6 > x /= 3 2 > x -= 2 0 >Không có khó khăn gì để hiểu các phép toán này.
Các phép toán với kiểu dữ liệu: type casting, is và as, typeof
Type casting
Type casting (tạm dịch là ép kiểu) là việc chuyển đổi giá trị của một biến sang một kiểu khác nhưng không làm thay đổi bản chất giá trị của nó. Ví dụ, C# tự động chuyển đổi giá trị giữa các kiểu số, như từ số nguyên sang số thực và ngược lại. Loại ép kiểu này được gọi là implicit casting.
Tuy nhiên, trong nhiều trường hợp C# không thể tự thực hiện được mà bạn phải tự mình chỉ định kiểu đích. Loại ép kiểu này được gọi là explicit casting.
Lưu ý, nếu bạn chuyển đổi từ chuỗi “1234” thành số 1234 hay ngược lại, dữ liệu đã bị thay đổi về bản chất. Đây được gọi là type conversion.
Để thực hiện type casting, bạn cần dùng phép toán casting theo cách sau:
(<kiểu-đích) <giá-trị>Biểu thức này sẽ thực hiện chuyển đổi <giá-trị> sang <kiểu-đích>. Nếu quá trình ép kiểu không thành công, biểu thức sẽ phát ra ngoại lệ (exception).
Ví dụ sau đây sẽ ép kiểu của biến o1 (kiểu object) sang kiểu string và gán vào biến str1:
> object o1 = "Hello world"; > string str1 = (string)o1; > str1 > string str2 = o1 as string; > str2 "Hello world" > object o2 = 12345; > string str3 = o2 as string; > str3 null >Tuy nhiên, phép toán as lại chỉ có thể áp dụng được đối với các kiểu tham chiếu (reference type). Nó không áp dụng được với kiểu giá trị (value type). Lý do là vì trong trường hợp ép kiểu không thành công, nó trả về giá trị null. Đây là giá trị đặc trưng riêng của kiểu tham chiếu (và kiểu nullable).
Kiểm tra kiểu – phép toán is
Để đảm bảo không gây lỗi khi ép kiểu, bạn nên kiểm tra kiểu (type checking) trước khi thực hiện.
C# sử dụng phép toán is để kiểm tra kiểu của một giá trị (object). Hãy thực hiện một vài ví dụ trên C# interactive:
> object o1 = "Hello world"; > o1 is string true > o1 is int > stringType [System.String] > stringType.UnderlyingSystemType [System.String] > stringType.Assembly [mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089] > stringType.BaseType [System.Object] > stringType.FullName "System.String"Lưu ý rằng, typeof chỉ nhận tham số là tên kiểu dữ liệu. Nếu muốn lấy thông tin về kiểu từ biến, bạn phải dùng phương thức GetType():
> stringType = "Hello world".GetType();Sự Khác Biệt Giữa For…In,And Foreach Trong Javascript
Nói về iterate trong javascript có rất nhiều cách để chúng ta có thể làm được điều đó như for, for … in, for … of. Thậm chí là reduce()… Nhưng bạn có biết vì sao javascript lại cung cấp nhiều method đến vậy, và nó có sự khác biệt gì. Trong bài viết này, chúng ta sẽ làm rõ những điều mà có thể bạn chưa hề biết.
For … in
Đầu tiên chúng ta nói về . được sử dụng để được sử dụng để lặp lại trên tất cả các enumerable properties của một Object, bao gồm enumerable properties được kế thừa. Câu lệnh lặp này có thể được sử dụng với String, Array, or những object đơn giản, nhưng không phải với các object như Map() hoặc Set().
Nhân tiện đây bạn nào chưa hiểu về “enumerable properties object”? Tôi sẽ nói thêm một chút khi bài viết này kết thúc.
Example For … in
for (let prop in ['a', 'b', 'c']) console.log(prop); for (let prop in 'str') console.log(prop); for (let prop in {a: 1, b: 2, c: 3}) console.log(prop); for (let prop in new Set(['a', 'b', 'a', 'd'])) console.log(prop);For … of
For … of được sử dụng để lặp qua các iterable objects, lặp lại các giá trị của chúng thay vì các thuộc tính của chúng. Câu lệnh lặp này có thể được sử dụng với các Array, String, Map hoặc Set object, nhưng nó không sử dụng trên những object đơn giản. Điều này có nghĩa là nó ngược với for … in.
Example For … of
for (let val of ['a', 'b', 'c']) console.log(val); for (let val of 'str') console.log(val); for (let val of {a: 1, b: 2, c: 3}) console.log(prop); for (let val of new Set(['a', 'b', 'a', 'd'])) console.log(val);forEach
forEach là một phương thức của Array prototype, cho phép bạn lặp lại các phần tử của một mảng. Trong khi forEach () chỉ lặp qua các mảng, nó có thể truy cập cả giá trị và chỉ mục của từng phần tử trong khi lặp.
Một điều chú ý ở đây, đó là forEach được sử dụng rộng rải nhưng vẫn có nhiều bất cập cho nên bạn có thể đọc những bài viết trước về cách sử dụng forEach() cụ thể hơn đó là Trời sinh ra for loop sao còn sinh array.forEach trong javascript?
Example foreach
['a', 'b', 'c'].forEach( ); ['a', 'b', 'c'].forEach( );Enumerable properties object có nghĩa là gì?
Enumerable properties nó đơn giản có nghĩa là thuộc tính sẽ hiển thị nếu bạn lặp lại đối tượng bằng vòng lặp chúng tôi hoặc Object.keys . Hãy xem xét một ví dụ đơn giản: Nói về object javascript
const obj = { purposeOfLife: 42, } Object.getOwnPropertyDescriptor(obj, 'purposeOfLife')Object.getOwnPropertyDescriptor() trả về một đối tượng với các characteristics của property. Trong trường hợp của chúng tôi, nó sẽ return:
{ value: 42, writable: true, enumerable: true, configurable: true }Như bạn đã thấy enumerable: true bởi vì mỗi new property có default enumerable: true
Nhưng nếu bạn muốn tạo một object có enumerable: false thì bạn làm thế nào? Để làm được điều đó bạn sẽ sử dụng method sau: Object.defineProperty()
Object.defineProperty(obj, 'flameWarTopic', { value: 'Angular2 vs ReactJS', configurable: true, writable: false, enumerable: false });Như đầu bài tôi đã nói rằng chúng ta nên tập trung vào chính vấn đề là phân biệt và khi nào nên sử dụng For … in, for … of và forEach(). Cho nên tôi chỉ dừng lại và giới thiệu gọn nhẹ cho bạn những tính năng trên. Nếu bài viết này giúp cho bạn, thì hãy giúp tôi share cho tất cả mọi người đều thấy. Xin cảm ơn!
Cập nhật thông tin chi tiết về Vòng Lặp Foreach Trong Lập Trình C# Cơ Bản trên website Channuoithuy.edu.vn. Hy vọng nội dung bài viết sẽ đáp ứng được nhu cầu của bạn, chúng tôi sẽ thường xuyên cập nhật mới nội dung để bạn nhận được thông tin nhanh chóng và chính xác nhất. Chúc bạn một ngày tốt lành!