Collections & LINQ · Lesson 25

Jagged arrays and per-row contracts

Process rows with different lengths without assuming a rectangular grid.

How it works

A jagged array is an array whose elements are arrays. Each inner array has its own length, so the representation can model uneven groups such as daily batches, shelves with different capacities, or students with different numbers of scores. It differs from a rectangular multidimensional array, where every row has the same number of columns.

The outer array determines how many rows exist, while each inner array determines its own valid element positions. An empty inner array can be a valid row with no observations. A null inner array is a different state and requires a separate policy if the element type permits it. Make those distinctions explicit rather than assuming every outer position contains a nonempty group.

Walk through the example. The sample contains a three-value row, an empty row, and a two-value row. The loop reads each inner array's Length and Sum independently. The empty row has a count and sum of zero, which are meaningful aggregate results. SelectMany then flattens all values into one sequence for an overall total of fifteen without inserting placeholder values for the empty row.

Watch the boundary. Using the first row's length as the bound for every other row can either skip data or access past a shorter row. A square or uniformly populated test case would hide that error. Also remember that copying only the outer array still shares the inner array objects. Independent nested snapshots require copying each row as well as the outer container.

Practice independently. Model four daily batches with different item counts, including an empty day. Print a total for each day and a total across all days. Add a function that returns an independent jagged-array snapshot and prove that changing one copied row does not change the original. Finally decide how a missing day should differ from a recorded day containing no items.

A working example

using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;

int[][] batches = { new[] { 1, 2, 3 }, Array.Empty<int>(), new[] { 4, 5 } };
for (int row = 0; row < batches.Length; row++)
    Console.WriteLine($"row{row}:count={batches[row].Length};sum={batches[row].Sum()}");
Console.WriteLine($"all:{batches.SelectMany(row => row).Sum()}");

Expected output

row0:count=3;sum=6
row1:count=0;sum=0
row2:count=2;sum=9
all:15
Try this
Use each inner array’s own length, and distinguish empty rows from missing rows.