@@ -630,11 +630,79 @@ fn position_elt<T>(v: [T], x: T) -> option::t<uint> {
630
630
/*
631
631
Function: position
632
632
633
- Find the first index for which the value matches some predicate
633
+ Find the first index matching some predicate
634
+
635
+ Apply function `f` to each element of `v`. When function `f` returns true
636
+ then an option containing the index is returned. If `f` matches no elements
637
+ then none is returned.
634
638
*/
635
639
fn position < T > ( v : [ T ] , f : fn ( T ) -> bool ) -> option:: t < uint > {
636
- let i: uint = 0 u;
637
- while i < len ( v) { if f ( v[ i] ) { ret some :: < uint > ( i) ; } i += 1 u; }
640
+ position_from ( v, 0 u, len ( v) , f)
641
+ }
642
+
643
+ /*
644
+ Function: position_from
645
+
646
+ Find the first index matching some predicate within a range
647
+
648
+ Apply function `f` to each element of `v` between the range [`start`, `end`).
649
+ When function `f` returns true then an option containing the index is
650
+ returned. If `f` matches no elements then none is returned.
651
+ */
652
+ fn position_from < T > ( v : [ T ] , start : uint , end : uint , f : fn ( T ) -> bool ) ->
653
+ option:: t < uint > {
654
+ assert start <= end;
655
+ assert end <= len ( v) ;
656
+ let i = start;
657
+ while i < end { if f ( v[ i] ) { ret some :: < uint > ( i) ; } i += 1 u; }
658
+ ret none;
659
+ }
660
+
661
+ /*
662
+ Function: rposition_elt
663
+
664
+ Find the last index containing a matching value
665
+
666
+ Returns:
667
+
668
+ option::some(uint) - The last index containing a matching value
669
+ option::none - No elements matched
670
+ */
671
+ fn rposition_elt < T > ( v : [ T ] , x : T ) -> option:: t < uint > {
672
+ rposition ( v) { |y| x == y }
673
+ }
674
+
675
+ /*
676
+ Function: rposition
677
+
678
+ Find the last index matching some predicate
679
+
680
+ Apply function `f` to each element of `v` in reverse order. When function
681
+ `f` returns true then an option containing the index is returned. If `f`
682
+ matches no elements then none is returned.
683
+ */
684
+ fn rposition < T > ( v : [ T ] , f : fn ( T ) -> bool ) -> option:: t < uint > {
685
+ rposition_from ( v, 0 u, len ( v) , f)
686
+ }
687
+
688
+ /*
689
+ Function: rposition_from
690
+
691
+ Find the last index matching some predicate within a range
692
+
693
+ Apply function `f` to each element of `v` in reverse order between the range
694
+ [`start`, `end`). When function `f` returns true then an option containing
695
+ the index is returned. If `f` matches no elements then none is returned.
696
+ */
697
+ fn rposition_from < T > ( v : [ T ] , start : uint , end : uint , f : fn ( T ) -> bool ) ->
698
+ option:: t < uint > {
699
+ assert start <= end;
700
+ assert end <= len ( v) ;
701
+ let i = end;
702
+ while i > start {
703
+ if f ( v[ i - 1 u] ) { ret some :: < uint > ( i - 1 u) ; }
704
+ i -= 1 u;
705
+ }
638
706
ret none;
639
707
}
640
708
@@ -1474,6 +1542,72 @@ mod tests {
1474
1542
}
1475
1543
1476
1544
#[ test]
1545
+ fn test_position_from ( ) {
1546
+ assert position_from ( [ ] , 0 u, 0 u, f) == none;
1547
+
1548
+ fn f ( xy : ( int , char ) ) -> bool { let ( _x, y) = xy; y == 'b' }
1549
+ let v = [ ( 0 , 'a' ) , ( 1 , 'b' ) , ( 2 , 'c' ) , ( 3 , 'b' ) ] ;
1550
+
1551
+ assert position_from ( v, 0 u, 0 u, f) == none;
1552
+ assert position_from ( v, 0 u, 1 u, f) == none;
1553
+ assert position_from ( v, 0 u, 2 u, f) == some ( 1 u) ;
1554
+ assert position_from ( v, 0 u, 3 u, f) == some ( 1 u) ;
1555
+ assert position_from ( v, 0 u, 4 u, f) == some ( 1 u) ;
1556
+
1557
+ assert position_from ( v, 1 u, 1 u, f) == none;
1558
+ assert position_from ( v, 1 u, 2 u, f) == some ( 1 u) ;
1559
+ assert position_from ( v, 1 u, 3 u, f) == some ( 1 u) ;
1560
+ assert position_from ( v, 1 u, 4 u, f) == some ( 1 u) ;
1561
+
1562
+ assert position_from ( v, 2 u, 2 u, f) == none;
1563
+ assert position_from ( v, 2 u, 3 u, f) == none;
1564
+ assert position_from ( v, 2 u, 4 u, f) == some ( 3 u) ;
1565
+
1566
+ assert position_from ( v, 3 u, 3 u, f) == none;
1567
+ assert position_from ( v, 3 u, 4 u, f) == some ( 3 u) ;
1568
+
1569
+ assert position_from ( v, 4 u, 4 u, f) == none;
1570
+ }
1571
+
1572
+ #[ test]
1573
+ fn test_rposition ( ) {
1574
+ assert find( [ ] , f) == none;
1575
+
1576
+ fn f ( xy : ( int , char ) ) -> bool { let ( _x, y) = xy; y == 'b' }
1577
+ fn g ( xy : ( int , char ) ) -> bool { let ( _x, y) = xy; y == 'd' }
1578
+ let v = [ ( 0 , 'a' ) , ( 1 , 'b' ) , ( 2 , 'c' ) , ( 3 , 'b' ) ] ;
1579
+
1580
+ assert position( v, f) == some ( 1 u) ;
1581
+ assert position( v, g) == none;
1582
+ }
1583
+
1584
+ #[ test]
1585
+ fn test_rposition_from ( ) {
1586
+ assert rposition_from ( [ ] , 0 u, 0 u, f) == none;
1587
+
1588
+ fn f ( xy : ( int , char ) ) -> bool { let ( _x, y) = xy; y == 'b' }
1589
+ let v = [ ( 0 , 'a' ) , ( 1 , 'b' ) , ( 2 , 'c' ) , ( 3 , 'b' ) ] ;
1590
+
1591
+ assert rposition_from ( v, 0 u, 0 u, f) == none;
1592
+ assert rposition_from ( v, 0 u, 1 u, f) == none;
1593
+ assert rposition_from ( v, 0 u, 2 u, f) == some ( 1 u) ;
1594
+ assert rposition_from ( v, 0 u, 3 u, f) == some ( 1 u) ;
1595
+ assert rposition_from ( v, 0 u, 4 u, f) == some ( 3 u) ;
1596
+
1597
+ assert rposition_from ( v, 1 u, 1 u, f) == none;
1598
+ assert rposition_from ( v, 1 u, 2 u, f) == some ( 1 u) ;
1599
+ assert rposition_from ( v, 1 u, 3 u, f) == some ( 1 u) ;
1600
+ assert rposition_from ( v, 1 u, 4 u, f) == some ( 3 u) ;
1601
+
1602
+ assert rposition_from ( v, 2 u, 2 u, f) == none;
1603
+ assert rposition_from ( v, 2 u, 3 u, f) == none;
1604
+ assert rposition_from ( v, 2 u, 4 u, f) == some ( 3 u) ;
1605
+
1606
+ assert rposition_from ( v, 3 u, 3 u, f) == none;
1607
+ assert rposition_from ( v, 3 u, 4 u, f) == some ( 3 u) ;
1608
+
1609
+ assert rposition_from ( v, 4 u, 4 u, f) == none;
1610
+ }
1477
1611
fn reverse_and_reversed ( ) {
1478
1612
let v: [ mutable int] = [ mutable 10 , 20 ] ;
1479
1613
assert ( v[ 0 ] == 10 ) ;
0 commit comments