Rules / Style / prefer-last

prefer-last

lint/style/prefer-last
recommended
Same as prefer-last · Dart Code Metrics

Flags manual last-element indexing in favor of the .last getter.

Catches the xs[xs.length - 1] idiom, where the receiver and the collection whose length is read are the same identifier. Iterables expose a dedicated .last getter that reads more clearly, avoids repeating the receiver, and removes the off-by-one arithmetic that manual indexing invites. The match is deliberately narrow: it requires a literal - 1 subtracted from <name>.length indexing <name>, so unrelated index expressions are left alone.

Invalid

example.dartdart
// Bad: using [list.length - 1] instead of .last
void example() {
  final items = [1, 2, 3];
  final last = items[items.length - 1];
  print(last);
}

class Processor {
  String getLastName(List<String> names) {
    return names[names.length - 1];
  }

  void processTail(List<int> values) {
    final tail = values[values.length - 1];
    if (tail > 0) {
      compute(tail);
    }
  }
}

void multipleViolations(List<String> items) {
  final a = items[items.length - 1];
  final b = items[items.length - 1].length;
  print('$a $b');
}
Prefer .last over [length - 1] to access the last element
3 final items = [1, 2, 3];
4 final last = items[items.length - 1];
Prefer .last over [length - 1] to access the last element
9 String getLastName(List<String> names) {
10 return names[names.length - 1];
Prefer .last over [length - 1] to access the last element
13 void processTail(List<int> values) {
14 final tail = values[values.length - 1];
Prefer .last over [length - 1] to access the last element
21void multipleViolations(List<String> items) {
22 final a = items[items.length - 1];
Prefer .last over [length - 1] to access the last element
22 final a = items[items.length - 1];
23 final b = items[items.length - 1].length;

Valid

example.dartdart
// Good: using .last
void example() {
  final items = [1, 2, 3];
  final last = items.last;
  print(last);
}

class Processor {
  String getLastName(List<String> names) {
    return names.last;
  }

  void processTail(List<int> values) {
    final tail = values.last;
    if (tail > 0) {
      compute(tail);
    }
  }
}

void multipleAccess(List<String> items) {
  final a = items.last;
  final b = items.last.length;
  print('$a $b');
}

// OK: accessing non-last indices
void accessOther(List<int> items) {
  final secondToLast = items[items.length - 2];
  final third = items[2];
}

// OK: in loop context
void loopAccess(List<List<int>> matrix) {
  for (int i = 0; i < matrix.length; i++) {
    final row = matrix[i]; // accessing by variable index is OK
  }
}

How to configure

Set the severity of prefer-last in your falcon.json:

falcon.jsonjson
{
  "linter": {
    "rules": {
      "style": {
        "prefer-last": "error"
      }
    }
  }
}