Skip to content
Algorand Developer Portal

Array Utilities

← Back to Common Utilities

This example demonstrates the array utility functions for comparing and concatenating byte arrays:

  • arrayEqual() for comparing two arrays element-by-element
  • concatArrays() for joining multiple Uint8Arrays into a new array
  • No LocalNet required

From the repository root:

Terminal window
cd examples
npm run example common/03-array-utilities.ts

View source on GitHub

03-array-utilities.ts
/**
* Example: Array Utilities
*
* This example demonstrates the array utility functions for comparing and
* concatenating byte arrays:
* - arrayEqual() for comparing two arrays element-by-element
* - concatArrays() for joining multiple Uint8Arrays into a new array
*
* Prerequisites:
* - No LocalNet required
*/
import { arrayEqual, concatArrays } from '@algorandfoundation/algokit-utils/common';
import { formatBytes, printHeader, printInfo, printStep, printSuccess } from '../shared/utils.js';
function main() {
printHeader('Array Utilities Example');
// Step 1: arrayEqual() - Comparing Equal Arrays
printStep(1, 'arrayEqual() - Comparing Equal Arrays');
const arr1 = new Uint8Array([1, 2, 3, 4, 5]);
const arr2 = new Uint8Array([1, 2, 3, 4, 5]);
printInfo(`Array 1: ${formatBytes(arr1)}`);
printInfo(`Array 2: ${formatBytes(arr2)}`);
printInfo(`arrayEqual(arr1, arr2): ${arrayEqual(arr1, arr2)}`);
printInfo(`Arrays with identical content return true`);
// Step 2: arrayEqual() - Different Length Arrays
printStep(2, 'arrayEqual() - Different Length Arrays');
const shortArr = new Uint8Array([1, 2, 3]);
const longArr = new Uint8Array([1, 2, 3, 4, 5]);
printInfo(`Short array (length ${shortArr.length}): ${formatBytes(shortArr)}`);
printInfo(`Long array (length ${longArr.length}): ${formatBytes(longArr)}`);
printInfo(`arrayEqual(shortArr, longArr): ${arrayEqual(shortArr, longArr)}`);
printInfo(`Different lengths return false (fast check before element comparison)`);
// Step 3: arrayEqual() - Same Length, Different Content
printStep(3, 'arrayEqual() - Same Length, Different Content');
const arrA = new Uint8Array([1, 2, 3, 4, 5]);
const arrB = new Uint8Array([1, 2, 99, 4, 5]); // Different value at index 2
printInfo(`Array A: ${formatBytes(arrA)}`);
printInfo(`Array B: ${formatBytes(arrB)}`);
printInfo(`arrayEqual(arrA, arrB): ${arrayEqual(arrA, arrB)}`);
printInfo(`Same length but different content at index 2 returns false`);
// Step 4: arrayEqual() - Edge Cases
printStep(4, 'arrayEqual() - Edge Cases');
// Empty arrays
const empty1 = new Uint8Array([]);
const empty2 = new Uint8Array([]);
printInfo(`Empty arrays: arrayEqual([], []): ${arrayEqual(empty1, empty2)}`);
// Single element
const single1 = new Uint8Array([42]);
const single2 = new Uint8Array([42]);
printInfo(`Single element: arrayEqual([42], [42]): ${arrayEqual(single1, single2)}`);
// Same reference
const sameRef = new Uint8Array([1, 2, 3]);
printInfo(`Same reference: arrayEqual(arr, arr): ${arrayEqual(sameRef, sameRef)}`);
// Step 5: concatArrays() - Joining Multiple Arrays
printStep(5, 'concatArrays() - Joining Multiple Arrays');
const first = new Uint8Array([1, 2, 3]);
const second = new Uint8Array([4, 5, 6]);
const third = new Uint8Array([7, 8, 9]);
printInfo(`First array: ${formatBytes(first)}`);
printInfo(`Second array: ${formatBytes(second)}`);
printInfo(`Third array: ${formatBytes(third)}`);
const concatenated = concatArrays(first, second, third);
printInfo(`\nconcatArrays(first, second, third):`);
printInfo(`Result: ${formatBytes(concatenated)}`);
printInfo(`Result length: ${concatenated.length} bytes`);
// Step 6: concatArrays() - Different Sized Arrays
printStep(6, 'concatArrays() - Different Sized Arrays');
const tiny = new Uint8Array([1]);
const small = new Uint8Array([2, 3]);
const medium = new Uint8Array([4, 5, 6, 7]);
const large = new Uint8Array([8, 9, 10, 11, 12, 13, 14, 15]);
printInfo(`Tiny (1 byte): ${formatBytes(tiny)}`);
printInfo(`Small (2 bytes): ${formatBytes(small)}`);
printInfo(`Medium (4 bytes): ${formatBytes(medium)}`);
printInfo(`Large (8 bytes): ${formatBytes(large)}`);
const combined = concatArrays(tiny, small, medium, large);
printInfo(`\nconcatArrays(tiny, small, medium, large):`);
printInfo(`Result: ${formatBytes(combined)}`);
printInfo(`Result length: ${combined.length} bytes (1 + 2 + 4 + 8 = 15)`);
// Step 7: concatArrays() Returns New Array (Doesn't Modify Inputs)
printStep(7, 'concatArrays() - Returns New Array (Non-Mutating)');
const original1 = new Uint8Array([10, 20, 30]);
const original2 = new Uint8Array([40, 50, 60]);
printInfo(`Before concat:`);
printInfo(` original1: ${formatBytes(original1)}`);
printInfo(` original2: ${formatBytes(original2)}`);
const result = concatArrays(original1, original2);
printInfo(`\nAfter concat:`);
printInfo(` original1: ${formatBytes(original1)} (unchanged)`);
printInfo(` original2: ${formatBytes(original2)} (unchanged)`);
printInfo(` result: ${formatBytes(result)} (new array)`);
// Prove they are different objects
printInfo(`\nVerifying result is a new array:`);
printInfo(` result === original1: ${result === original1}`);
printInfo(` result === original2: ${result === original2}`);
// Modify result and show originals are unaffected
result[0] = 99;
printInfo(`\nAfter modifying result[0] = 99:`);
printInfo(` result: ${formatBytes(result)}`);
printInfo(` original1: ${formatBytes(original1)} (still unchanged)`);
// Step 8: concatArrays() - Edge Cases
printStep(8, 'concatArrays() - Edge Cases');
// Single array
const singleInput = new Uint8Array([1, 2, 3]);
const singleResult = concatArrays(singleInput);
printInfo(`Single input: concatArrays([1,2,3]) = ${formatBytes(singleResult)}`);
printInfo(` Is new array: ${singleResult !== singleInput}`);
// Empty arrays
const emptyResult = concatArrays(new Uint8Array([]), new Uint8Array([1, 2]), new Uint8Array([]));
printInfo(`With empty arrays: concatArrays([], [1,2], []) = ${formatBytes(emptyResult)}`);
// No arguments
const noArgs = concatArrays();
printInfo(`No arguments: concatArrays() = ${formatBytes(noArgs)} (empty array)`);
// Step 9: Practical Use Cases
printStep(9, 'Practical Use Cases');
printInfo('Common scenarios for array utilities:');
printInfo('\n1. Comparing cryptographic hashes:');
const hash1 = new Uint8Array([0xab, 0xcd, 0xef, 0x12]);
const hash2 = new Uint8Array([0xab, 0xcd, 0xef, 0x12]);
printInfo(` hash1 === hash2 (reference): ${hash1 === hash2}`);
printInfo(` arrayEqual(hash1, hash2) (content): ${arrayEqual(hash1, hash2)}`);
printInfo('\n2. Building transaction data:');
const prefix = new Uint8Array([0x54, 0x58]); // "TX"
const txData = new Uint8Array([0x01, 0x02, 0x03]);
const prefixedTx = concatArrays(prefix, txData);
printInfo(` Prefix + TxData: ${formatBytes(prefixedTx)}`);
printInfo('\n3. Concatenating signature components:');
const r = new Uint8Array([0x30, 0x31, 0x32, 0x33]); // r component
const s = new Uint8Array([0x40, 0x41, 0x42, 0x43]); // s component
const signature = concatArrays(r, s);
printInfo(` r + s = ${formatBytes(signature)}`);
// Step 10: Summary
printStep(10, 'Summary');
printInfo('Array Comparison:');
printInfo(' - arrayEqual(a, b) - Compare two arrays element-by-element');
printInfo(' - Returns false immediately if lengths differ (efficient)');
printInfo(' - Works with any ArrayLike<T> type');
printInfo('\nArray Concatenation:');
printInfo(' - concatArrays(...arrays) - Join multiple Uint8Arrays');
printInfo(' - Returns a new Uint8Array (non-mutating)');
printInfo(' - Works with any ArrayLike<number> type');
printInfo(' - Handles empty arrays and single inputs gracefully');
printSuccess('Array Utilities example completed successfully!');
}
main();