@@ -274,12 +274,26 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
274274 * Iterate over all elements of the array.
275275 *
276276 * The callback will be passed an element and a boolean `isDummy` indicating
277- * whether the value is part of the actual array.
277+ * whether the value is part of the actual array. Optionally, an index can be
278+ * passed as a third argument (used in `forEachReversed`)
278279 */
279- forEach ( f : ( t : ProvableValue , isDummy : Bool ) => void ) {
280- zip ( this . array , this . #dummyMask( ) ) . forEach ( ( [ t , isDummy ] ) => {
281- f ( t , isDummy ) ;
282- } ) ;
280+ forEach ( f : ( t : ProvableValue , isDummy : Bool , i ?: number ) => void ) : void {
281+ zip ( this . array , this . #dummyMask( ) ) . forEach ( ( [ t , isDummy ] , i ) => f ( t , isDummy , i ) ) ;
282+ }
283+
284+ /**
285+ * Iterate over all elements of the array, in reverse order.
286+ *
287+ * The callback will be passed an element and a boolean `isDummy` indicating whether the value is part of the actual array.
288+ *
289+ * Note: the indices are also passed in reverse order, i.e. we always have `t = this.array[i]`.
290+ */
291+ forEachReverse ( f : ( t : ProvableValue , isDummy : Bool , i : number ) => void ) {
292+ zip ( this . array , this . #dummyMask( ) )
293+ . reverse ( )
294+ . forEach ( ( [ t , isDummy ] , i ) => {
295+ f ( t , isDummy , this . capacity - 1 - i ) ;
296+ } ) ;
283297 }
284298
285299 /**
@@ -519,6 +533,21 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
519533 return sliced ;
520534 }
521535
536+ /**
537+ * Returns a new array with the elements reversed.
538+ */
539+ reverse ( ) : DynamicArray < ProvableValue , Value > {
540+ let Array = DynamicArray ( this . innerType , { capacity : this . capacity } ) ;
541+ // first, copy the inner array of length capacity and reverse it
542+ let array = this . array . slice ( ) . reverse ( ) ;
543+
544+ // now, slice off the padding that is now at the beginning of the array
545+ let capacity = new Field ( this . capacity ) ;
546+ return new Array ( array , capacity ) . slice (
547+ capacity . sub ( this . length ) . seal ( )
548+ ) ;
549+ }
550+
522551 /**
523552 * Concatenates the current array with another dynamic array, returning a new
524553 * dynamic array with the values of both arrays. The capacity of the new array
0 commit comments