วิธีที่ดีที่สุดในการวนกลับใน C / C # / C ++ คืออะไร?


101

ฉันต้องการเลื่อนไปข้างหลังผ่านอาร์เรย์ดังนั้นฉันจึงมีรหัสดังนี้:

for (int i = myArray.Length - 1; i >= 0; i--)
{
    // Do something
    myArray[i] = 42;
}

มีวิธีที่ดีกว่านี้หรือไม่?

อัปเดต: ฉันหวังว่า C # อาจมีกลไกในตัวสำหรับสิ่งนี้:

foreachbackwards (int i in myArray)
{
    // so easy
}

การปรับปรุงที่ 2: มีมีวิธีที่ดีกว่า Rune รับรางวัลด้วย:

for (int i = myArray.Length; i-- > 0; )
{    
    //do something
}
//or
for (int i = myArray.Length; i --> 0; )
{
    // do something
}

ซึ่งดูดียิ่งขึ้นใน C ปกติ (ขอบคุณ Twotymz):

for (int i = lengthOfArray; i--; )
{    
    //do something
}

ฉันไม่แน่ใจว่าฉันเข้าใจว่าเหตุใดทางเลือกอื่นจึงดีกว่าถ้าความดีมีความชัดเจนหรือการบำรุงรักษา
dkretz

จริง. ฉันหวังว่าจะพบวิธีที่สมเหตุสมผลกว่านี้ในการทำเช่นนี้เนื่องจากฉันต้องทำบ่อยพอสมควร
MusiGenesis

3
คำถามนี้ส่วนใหญ่เป็นการทบทวนคำตอบด้านล่าง แนะนำให้ย่อลงอย่างมีนัยสำคัญ
einpoklum

โปรดลบ C และ C ++ ออกจากชื่อและแฮชแท็ก
jaskmar

คำตอบ:


149

แม้ว่าจะค่อนข้างคลุมเครือ แต่ฉันก็บอกได้ว่าวิธีการพิมพ์ที่ถูกใจที่สุดในการทำเช่นนี้คือ

for (int i = myArray.Length; i --> 0; )
{
    //do something
}

32
เมื่อฉันอ่านคำตอบของคุณเป็นครั้งแรกดูเหมือนว่าจะไม่รวบรวมด้วยซ้ำดังนั้นฉันจึงถือว่าคุณเป็นคนบ้า แต่มันคือสิ่งที่ฉันกำลังมองหานั่นคือวิธีที่ดีกว่าในการเขียนย้อนกลับสำหรับการวนซ้ำ
MusiGenesis

3
ฉันคิดว่าฉัน -> 0; เป็นไปตามวัตถุประสงค์ นั่นคือสิ่งที่เขาหมายถึงโดย "พิมพ์ถูกใจ"
Johannes Schaub - litb

16
ฉันพบว่าตัวเอง "พิมพ์สับสน" สำหรับฉันแล้ว "-" จะดูไม่ถูกต้องเว้นแต่ว่าจะอยู่ติดกับตัวแปรที่มีผลกระทบ
MusiGenesis

26
มันคลุมเครือและสับสนเกินไป ฉันจะไม่เขียนอะไรแบบนี้ในรหัสการผลิต ...
Mihai Todor

9
Aah the ไปที่ตัวดำเนินการ (->)ทำเคล็ดลับ!
nawfal

118

ใน C ++ คุณมีตัวเลือกพื้นฐานระหว่างการวนซ้ำโดยใช้ตัววนซ้ำหรือดัชนี ขึ้นอยู่กับว่าคุณมีอาร์เรย์ธรรมดาหรือstd::vectorคุณใช้เทคนิคต่างๆ

ใช้ std :: vector

การใช้ตัวทำซ้ำ

C ++ ช่วยให้คุณสามารถทำได้โดยใช้ std::reverse_iterator:

for(std::vector<T>::reverse_iterator it = v.rbegin(); it != v.rend(); ++it) {
    /* std::cout << *it; ... */
}

การใช้ดัชนี

ชนิดหนึ่งที่ไม่ได้ลงชื่อกลับโดยstd::vector<T>::sizeเป็นไม่ได้std::size_tเสมอ อาจมากกว่าหรือน้อยกว่า นี่เป็นสิ่งสำคัญสำหรับการวนซ้ำในการทำงาน

for(std::vector<int>::size_type i = someVector.size() - 1; 
    i != (std::vector<int>::size_type) -1; i--) {
    /* std::cout << someVector[i]; ... */
}

มันใช้งานได้เนื่องจากค่าประเภทอินทิกรัลที่ไม่ได้ลงชื่อถูกกำหนดโดยวิธีการโมดูโลจำนวนบิต ดังนั้นหากคุณกำลังตั้งค่า-Nคุณจะจบลงที่(2 ^ BIT_SIZE) -N

การใช้อาร์เรย์

การใช้ตัวทำซ้ำ

เรากำลังใช้std::reverse_iteratorในการทำซ้ำ

for(std::reverse_iterator<element_type*> it(a + sizeof a / sizeof *a), itb(a); 
    it != itb; 
    ++it) {
    /* std::cout << *it; .... */
}

การใช้ดัชนี

เราสามารถใช้std::size_tที่นี่ได้อย่างปลอดภัยเมื่อเทียบกับข้างต้นเนื่องจากsizeofจะส่งคืนstd::size_tตามคำจำกัดความเสมอ

for(std::size_t i = (sizeof a / sizeof *a) - 1; i != (std::size_t) -1; i--) {
   /* std::cout << a[i]; ... */
}

หลีกเลี่ยงข้อผิดพลาดด้วย sizeof ที่ใช้กับพอยน์เตอร์

จริงๆแล้ววิธีการข้างต้นในการกำหนดขนาดของอาร์เรย์นั้นแย่มาก หาก a เป็นตัวชี้แทนที่จะเป็นอาร์เรย์ (ซึ่งเกิดขึ้นค่อนข้างบ่อยและผู้เริ่มต้นจะสับสน) มันจะล้มเหลวโดยเงียบ วิธีที่ดีกว่าคือใช้สิ่งต่อไปนี้ซึ่งจะล้มเหลวในเวลาคอมไพล์หากมีตัวชี้:

template<typename T, std::size_t N> char (& array_size(T(&)[N]) )[N];

ทำงานโดยรับขนาดของอาร์เรย์ที่ส่งผ่านก่อนจากนั้นประกาศให้ส่งคืนการอ้างอิงไปยังอาร์เรย์ประเภทถ่านที่มีขนาดเท่ากัน charถูกกำหนดให้มีsizeof: 1. ดังนั้นอาร์เรย์ที่ส่งคืนจะมี a sizeof: N * 1 ซึ่งเป็นสิ่งที่เรากำลังมองหาโดยมีเพียงการรวบรวมการประเมินเวลาและค่าใช้จ่ายรันไทม์เป็นศูนย์

แทนที่จะทำ

(sizeof a / sizeof *a)

เปลี่ยนรหัสของคุณเพื่อให้เป็นไปตามนั้น

(sizeof array_size(a))

นอกจากนี้หากคอนเทนเนอร์ของคุณไม่มีตัวทำซ้ำย้อนกลับคุณสามารถใช้การใช้ reverse_iterator ของ boost: boost.org/doc/libs/1_36_0/libs/iterator/doc/…
MP24

array_size ของคุณดูเหมือนจะใช้งานได้กับอาร์เรย์ที่จัดสรรแบบคงที่ แต่ล้มเหลวสำหรับฉันเมื่อ a เป็น 'new int [7]' เช่น
Nate Parsons

2
ใช่นั่นคือเจตนาของมัน :) new int [7] ส่งกลับตัวชี้ ดังนั้น sizeof (new int [7]) จะส่งกลับไม่ใช่ 7 * sizeof (int) แต่จะคืนค่า sizeof (int *) array_size ทำให้เกิดข้อผิดพลาดในการคอมไพล์สำหรับกรณีนั้นแทนที่จะทำงานแบบไม่โต้ตอบ
Johannes Schaub - litb

ลอง array_size (+ statically_allocated_array) ซึ่งล้มเหลวเช่นกันเนื่องจากตัวดำเนินการ + ทำให้อาร์เรย์เป็นตัวชี้ไปยังองค์ประกอบแรก การใช้ sizeof ธรรมดาจะทำให้คุณได้ขนาดของตัวชี้อีกครั้ง
Johannes Schaub - litb

สำหรับสิ่งแรก - ทำไมไม่เพียงแค่ใช้endและbeginในลำดับย้อนกลับ?
Tomáš Zato - คืนสถานะ Monica

54

ใน C #โดยใช้ Visual Studio 2005 หรือหลังจากนั้นพิมพ์ 'forr และตี [Tab] [Tab] สิ่งนี้จะขยายเป็นforลูปที่ย้อนกลับไปยังคอลเลคชัน

มันง่ายมากที่จะทำผิด (อย่างน้อยสำหรับฉัน) ฉันคิดว่าการใส่ตัวอย่างข้อมูลนี้จะเป็นความคิดที่ดี

ที่กล่าวว่าฉันชอบArray.Reverse()/ Enumerable.Reverse()แล้วทำซ้ำไปข้างหน้าดีกว่า - พวกเขาระบุเจตนาชัดเจนมากขึ้น


41

ฉันมักจะชอบรหัสที่ชัดเจนเมื่อเทียบกับรหัส ' พิมพ์ถูกใจ ' ดังนั้นฉันมักจะใช้:

for (int i = myArray.Length - 1; i >= 0; i--)  
{  
    // Do something ...  
}    

คุณสามารถพิจารณาว่าเป็นวิธีมาตรฐานในการวนกลับ
แค่สองเซ็นต์ของฉัน ...


ทำงานแล้ว ยังไม่ได้ทำใน C # แต่ขอบคุณ
PCPGMR

แล้วถ้าอาร์เรย์มีขนาดใหญ่มาก (ดังนั้นดัชนีจะต้องเป็นประเภทที่ไม่ได้ลงชื่อ)? size_t ไม่ได้ลงนามจริงหรือไม่
lalala

คุณสามารถประกาศว่าฉันเป็น uint ได้ดูโพสต์ของ Marc Gravell
Jack Griffin

ไม่สามารถใช้กับประเภทที่ไม่ได้ลงนามเนื่องจากการห่อซึ่งแตกต่างจากประเภทที่พิมพ์ได้ตามต้องการ ไม่ดี.
Ocelot

17

ในC #โดยใช้Linq :

foreach(var item in myArray.Reverse())
{
    // do something
}

นี่เป็นวิธีที่ง่ายที่สุด แต่โปรดทราบว่าในเวอร์ชันปัจจุบันของ CLR การย้อนกลับรายการจะเป็นการดำเนินการ O (n) เสมอแทนที่จะเป็นการดำเนินการ O (1) ซึ่งอาจเป็นได้ถ้าเป็น IList <T>; ดูconnect.microsoft.com/VisualStudio/feedback/…
Greg Beech

1
ดูเหมือนว่า. Reverse () จะสร้างสำเนาของอาร์เรย์ในเครื่องแล้ววนซ้ำไปมา ดูเหมือนว่าจะไม่มีประสิทธิภาพในการคัดลอกอาร์เรย์เพียงเพื่อให้คุณสามารถทำซ้ำได้ ฉันเดาว่าโพสต์ที่มี "Linq" ควรค่าแก่การโหวต :)
MusiGenesis

มีการแลกเปลี่ยนที่เป็นไปได้ แต่คุณพบปัญหาว่า "โหวตให้คำตอบ" (i -> 0) อาจส่งผลให้โค้ดช้าลงเนื่องจาก (i) ต้องตรวจสอบกับขนาดของอาร์เรย์ทุกครั้งที่เป็น ใช้เป็นดัชนี
Keltex

1
ในขณะที่ฉันยอมรับว่า Linq นั้นยอดเยี่ยม แต่ปัญหาของวิธีนี้คือตัววนซ้ำไม่อนุญาตให้คุณเลือกรายการของอาร์เรย์ - พิจารณาสถานการณ์ที่คุณต้องการนำทางผ่านบางส่วนของ Array แต่ไม่ใช่ทั้งหมด สิ่ง ...
jesses.co.tt

11

นั่นเป็นวิธีที่ดีที่สุดสำหรับอาร์เรย์ใด ๆ ที่มีความยาวเป็นอินทิกรัลที่ลงนาม สำหรับอาร์เรย์ที่มีความยาวเป็นประเภทอินทิกรัลที่ไม่ได้ลงชื่อ (เช่นstd::vectorใน C ++) คุณต้องแก้ไขเงื่อนไขสุดท้ายเล็กน้อย:

for(size_t i = myArray.size() - 1; i != (size_t)-1; i--)
    // blah

ถ้าคุณบอกว่าi >= 0นี่จะเป็นจริงเสมอสำหรับจำนวนเต็มที่ไม่ได้ลงนามดังนั้นลูปจะเป็นลูปแบบไม่สิ้นสุด


ใน C ++ "i--" จะพันรอบเป็นค่าสูงสุดโดยอัตโนมัติถ้าฉันเป็น 0? ขออภัยฉันบกพร่อง C ++
MusiGenesis

น่าอัศจรรย์. พวกคุณช่วยให้ฉันเข้าใจสาเหตุของข้อผิดพลาดในการเติมฮาร์ดไดรฟ์ในสิ่งที่ฉันเขียนเมื่อ 12 ปีก่อน สิ่งที่ดีฉันไม่ทำงานใน C ++
MusiGenesis

เงื่อนไขการสิ้นสุดควรเป็น: i <myArray.size () ขึ้นอยู่กับคุณสมบัติล้นของ int ที่ไม่ได้ลงนามเท่านั้น ไม่ใช่รายละเอียดการใช้งานของจำนวนเต็มและ casts ดังนั้นจึงง่ายต่อการอ่านและทำงานในภาษาที่มีการแทนจำนวนเต็มอื่น
ejgottl

ฉันคิดว่าทางออกที่ดีกว่าสำหรับฉันคืออยู่ในโลก C # ที่ฉันไม่สามารถทำร้ายใครได้
MusiGenesis

4

ดูดีกับผม. หากตัวทำดัชนีไม่ได้ลงนาม (uint ฯลฯ ) คุณอาจต้องคำนึงถึงสิ่งนั้นด้วย เรียกฉันว่าขี้เกียจ แต่ในกรณีนั้น (ไม่ได้ลงนาม) ฉันอาจใช้ตัวนับตัวแปร:

uint pos = arr.Length;
for(uint i = 0; i < arr.Length ; i++)
{
    arr[--pos] = 42;
}

(จริงๆแล้วคุณต้องระวังกรณีเช่น arr.Length = uint.MaxValue ... อาจจะเป็น! = ที่ไหนสักแห่ง ... แน่นอนว่าเป็นกรณีที่ไม่น่าเป็นไปได้มาก!)


แม้ว่าสิ่งที่ "--pos" จะยุ่งยาก ในอดีตฉันเคยมีเพื่อนร่วมงานที่ชื่นชอบการ "แก้ไข" แบบสุ่มในโค้ดซึ่งดูไม่ค่อยถูกต้องสำหรับพวกเขา
MusiGenesis

1
จากนั้นใช้. arr.Length-1 และ pos--
Marc Gravell

4

ใน CI ต้องการทำสิ่งนี้:


int i = myArray.Length;
while (i--) {
  myArray[i] = 42;
}

ตัวอย่าง C # ที่เพิ่มโดย MusiGenesis:

{int i = myArray.Length; while (i-- > 0)
{
    myArray[i] = 42;
}}

ฉันชอบสิ่งนี้. ฉันใช้เวลาสักสองหรือสองวินาทีกว่าจะรู้ว่าวิธีของคุณใช้ได้ผล หวังว่าคุณจะไม่สนใจเวอร์ชัน C # ที่เพิ่มเข้ามา (วงเล็บปีกกาพิเศษเพื่อให้ดัชนีถูกกำหนดขอบเขตเช่นเดียวกับในลูป)
MusiGenesis

ฉันไม่แน่ใจว่าจะใช้สิ่งนี้ในรหัสการผลิตเพราะมันจะทำให้เกิด "WTF is this?" แบบสากล ปฏิกิริยาจากใครก็ตามที่ต้องรักษาไว้ แต่จริงๆแล้วมันง่ายกว่าการพิมพ์แบบปกติสำหรับการวนซ้ำและไม่มีเครื่องหมายลบหรือ> = สัญลักษณ์
MusiGenesis

1
น่าเสียดายที่เวอร์ชัน C # ต้องการ "> 0" เพิ่มเติม
MusiGenesis

ฉันไม่แน่ใจว่ามันคือภาษาอะไร แต่ข้อมูลโค้ดแรกของคุณไม่ใช่ C :) เพียงเพื่อบอกให้คุณทราบอย่างชัดเจน บางทีคุณอาจต้องการเขียน C # และ html ล้มเหลวในการแยกวิเคราะห์หรืออะไร?
Johannes Schaub - litb

@litb: ฉันเดาว่า "myArray.Length" ไม่ถูกต้อง C (?) แต่ส่วน while loop ใช้งานได้และดูดี
MusiGenesis

3

วิธีที่ดีที่สุดในการทำเช่นนั้นใน C ++ อาจใช้อะแดปเตอร์ตัววนซ้ำ (หรือดีกว่าช่วง) ซึ่งจะเปลี่ยนลำดับอย่างเกียจคร้านในขณะที่กำลังเคลื่อนที่

โดยพื้นฐานแล้ว

vector<value_type> range;
foreach(value_type v, range | reversed)
    cout << v;

แสดงช่วง "range" (ที่นี่ว่างเปล่า แต่ฉันค่อนข้างแน่ใจว่าคุณสามารถเพิ่มองค์ประกอบได้ด้วยตัวเอง) ในลำดับย้อนกลับ แน่นอนว่าการทำซ้ำช่วงนั้นไม่ได้ใช้ประโยชน์มากนัก แต่การส่งต่อช่วงใหม่ไปยังอัลกอริทึมและสิ่งต่างๆนั้นค่อนข้างดี

กลไกนี้ยังสามารถใช้เพื่อการใช้งานที่มีประสิทธิภาพมากขึ้น:

range | transformed(f) | filtered(p) | reversed

จะคำนวณช่วง "range" อย่างเกียจคร้านโดยที่ฟังก์ชัน "f" ถูกนำไปใช้กับองค์ประกอบทั้งหมดองค์ประกอบที่ "p" ไม่เป็นจริงจะถูกลบออกและในที่สุดช่วงผลลัพธ์จะกลับรายการ

ไวยากรณ์ของท่อเป็น IMO ที่อ่านได้มากที่สุดเนื่องจากเป็น infix การอัปเดตไลบรารี Boost.Range ที่รอการตรวจสอบจะใช้สิ่งนี้ แต่ก็ค่อนข้างง่ายที่จะทำด้วยตัวเอง มันเจ๋งกว่าด้วยแลมบ์ดา DSEL เพื่อสร้างฟังก์ชัน f และเพรดิเคต p ในบรรทัด


บอกเราได้ไหมว่าคุณมี "foreach" มาจากไหน เป็น # กำหนดเป็น BOOST_FOREACH หรือไม่ ดูน่ารักตลอดทาง
Johannes Schaub - litb


1

ฉันชอบการวนซ้ำ มันชัดเจนสำหรับฉันมากกว่าการลดลงiในเงื่อนไขของ for loop

int i = arrayLength;
while(i)
{
    i--;
    //do something with array[i]
}

0

ฉันจะใช้รหัสในคำถามเดิม แต่ถ้าคุณต้องการใช้ foreach และมีดัชนีจำนวนเต็มใน C #:

foreach (int i in Enumerable.Range(0, myArray.Length).Reverse())
{
    myArray[i] = 42; 
}

-1

ฉันจะลองตอบคำถามของตัวเองที่นี่ แต่ฉันก็ไม่ค่อยชอบสิ่งนี้เช่นกัน:

for (int i = 0; i < myArray.Length; i++)
{
    int iBackwards = myArray.Length - 1 - i; // ugh
    myArray[iBackwards] = 666;
}

แทนที่จะทำ. length - 1 - i ทุกครั้งอาจพิจารณาตัวแปรที่สอง? ดูโพสต์ [อัปเดต] ของฉัน
Marc Gravell

โหวตลงในคำถามของฉันเอง รุนแรง. มันไม่ได้ดูแน่นหนาไปกว่าเดิม
MusiGenesis

-4

หมายเหตุ: โพสต์นี้มีรายละเอียดมากขึ้นดังนั้นจึงไม่อยู่ในหัวข้อนี้ฉันต้องขออภัย

ที่บอกว่าเพื่อนของฉันอ่านและเชื่อว่ามันมีค่า 'ที่ไหนสักแห่ง' กระทู้นี้ไม่ใช่สถานที่ ฉันขอขอบคุณสำหรับความคิดเห็นของคุณเกี่ยวกับสถานที่ที่ควรไป (ฉันยังใหม่กับไซต์นี้)


อย่างไรก็ตามนี่คือเวอร์ชัน C # ใน. NET 3.5 ซึ่งน่าทึ่งมากที่ทำงานกับคอลเลกชันทุกประเภทโดยใช้ความหมายที่กำหนด นี่เป็นการวัดค่าเริ่มต้น (ใช้ซ้ำ!) ไม่ใช่ประสิทธิภาพหรือการลดรอบของ CPU ในสถานการณ์ dev ที่พบบ่อยที่สุดแม้ว่าจะไม่เคยเป็นสิ่งที่เกิดขึ้นในโลกแห่งความเป็นจริง (การเพิ่มประสิทธิภาพก่อนกำหนด)

*** วิธีการขยายที่ทำงานกับประเภทคอลเลกชันใด ๆ และดำเนินการกับผู้แทนการดำเนินการที่คาดหวังว่าค่าประเภทเดียวทั้งหมดจะดำเนินการกับแต่ละรายการในทางกลับกัน **

ต้องการ 3.5:

public static void PerformOverReversed<T>(this IEnumerable<T> sequenceToReverse, Action<T> doForEachReversed)
      {
          foreach (var contextItem in sequenceToReverse.Reverse())
              doForEachReversed(contextItem);
      }

NET เวอร์ชันเก่ากว่าหรือคุณต้องการทำความเข้าใจ Linq internals ให้ดีขึ้นหรือไม่? อ่านต่อ .. หรือเปล่า ..

ASSUMPTION: ในระบบชนิด. NET ประเภท Array จะสืบทอดมาจากอินเทอร์เฟซ IEnumerable (ไม่ใช่ IE ทั่วไปที่สามารถคำนวณได้เฉพาะ IEnumerable)

นี่คือสิ่งที่คุณต้องทำซ้ำตั้งแต่ต้นจนจบอย่างไรก็ตามคุณต้องการไปในทิศทางตรงกันข้าม เนื่องจาก IEnumerable ทำงานบน Array ของประเภท 'object' ทุกประเภทจึงถูกต้อง

การวัดผลที่สำคัญ: เราถือว่าหากคุณสามารถประมวลผลลำดับใด ๆ ในลำดับย้อนกลับที่ 'ดีกว่า' จากนั้นจะสามารถทำได้เฉพาะกับจำนวนเต็มเท่านั้น

โซลูชันกสำหรับ. NET CLR 2.0-3.0:

คำอธิบาย: เราจะยอมรับอินสแตนซ์ที่นำไปใช้งานได้ของ IE โดยมีคำสั่งว่าอินสแตนซ์แต่ละอินสแตนซ์นั้นมีประเภทเดียวกัน ดังนั้นหากเราได้รับอาร์เรย์อาร์เรย์ทั้งหมดจะมีอินสแตนซ์ประเภท X หากอินสแตนซ์อื่น ๆ เป็นประเภท! = X จะมีการยกเว้น:

บริการเดี่ยว:

คลาสสาธารณะ ReverserService {private ReverserService () {}

    /// <summary>
    /// Most importantly uses yield command for efficiency
    /// </summary>
    /// <param name="enumerableInstance"></param>
    /// <returns></returns>
    public static IEnumerable ToReveresed(IEnumerable enumerableInstance)
    {
        if (enumerableInstance == null)
        {
            throw new ArgumentNullException("enumerableInstance");
        }

        // First we need to move forwarad and create a temp
        // copy of a type that allows us to move backwards
        // We can use ArrayList for this as the concrete
        // type

        IList reversedEnumerable = new ArrayList();
        IEnumerator tempEnumerator = enumerableInstance.GetEnumerator();

        while (tempEnumerator.MoveNext())
        {
            reversedEnumerable.Add(tempEnumerator.Current);
        }

        // Now we do the standard reverse over this using yield to return
        // the result
        // NOTE: This is an immutable result by design. That is 
        // a design goal for this simple question as well as most other set related 
        // requirements, which is why Linq results are immutable for example
        // In fact this is foundational code to understand Linq

        for (var i = reversedEnumerable.Count - 1; i >= 0; i--)
        {
            yield return reversedEnumerable[i];
        }
    }
}



public static class ExtensionMethods
{

      public static IEnumerable ToReveresed(this IEnumerable enumerableInstance)
      {
          return ReverserService.ToReveresed(enumerableInstance);
      }
 }

[TestFixture] คลาสสาธารณะ Testing123 {

    /// <summary>
    /// .NET 1.1 CLR
    /// </summary>
    [Test]
    public void Tester_fornet_1_dot_1()
    {
        const int initialSize = 1000;

        // Create the baseline data
        int[] myArray = new int[initialSize];

        for (var i = 0; i < initialSize; i++)
        {
            myArray[i] = i + 1;
        }

        IEnumerable _revered = ReverserService.ToReveresed(myArray);

        Assert.IsTrue(TestAndGetResult(_revered).Equals(1000));
    }

    [Test]
    public void tester_why_this_is_good()
    {

        ArrayList names = new ArrayList();
        names.Add("Jim");
        names.Add("Bob");
        names.Add("Eric");
        names.Add("Sam");

        IEnumerable _revered = ReverserService.ToReveresed(names);

        Assert.IsTrue(TestAndGetResult(_revered).Equals("Sam"));


    }

    [Test]
    public void tester_extension_method()
  {

        // Extension Methods No Linq (Linq does this for you as I will show)
        var enumerableOfInt = Enumerable.Range(1, 1000);

        // Use Extension Method - which simply wraps older clr code
        IEnumerable _revered = enumerableOfInt.ToReveresed();

        Assert.IsTrue(TestAndGetResult(_revered).Equals(1000));


    }


    [Test]
    public void tester_linq_3_dot_5_clr()
    {

        // Extension Methods No Linq (Linq does this for you as I will show)
        IEnumerable enumerableOfInt = Enumerable.Range(1, 1000);

        // Reverse is Linq (which is are extension methods off IEnumerable<T>
        // Note you must case IEnumerable (non generic) using OfType or Cast
        IEnumerable _revered = enumerableOfInt.Cast<int>().Reverse();

        Assert.IsTrue(TestAndGetResult(_revered).Equals(1000));


    }



    [Test]
    public void tester_final_and_recommended_colution()
    {

        var enumerableOfInt = Enumerable.Range(1, 1000);
        enumerableOfInt.PerformOverReversed(i => Debug.WriteLine(i));

    }



    private static object TestAndGetResult(IEnumerable enumerableIn)
    {
      //  IEnumerable x = ReverserService.ToReveresed(names);

        Assert.IsTrue(enumerableIn != null);
        IEnumerator _test = enumerableIn.GetEnumerator();

        // Move to first
        Assert.IsTrue(_test.MoveNext());
        return _test.Current;
    }
}

2
Dude or dudette: ฉันแค่มองหาวิธีการเขียนที่ไม่ค่อยเกะกะ "สำหรับ (int i = myArray.Length - 1; i> = 0; i--)"
MusiGenesis

1
คำตอบนี้ไม่มีค่าเลย
Matt Melton
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.