if_switch_linter: Require usage of switch() over repeated if/else blocks

View source: R/if_switch_linter.R

if_switch_linterR Documentation

Require usage of switch() over repeated if/else blocks

Description

switch() statements in R are used to delegate behavior based on the value of some input scalar string, e.g. switch(x, a = 1, b = 3, c = 7, d = 8) will be one of 1, 3, 7, or 8, depending on the value of x.

Usage

if_switch_linter(max_branch_lines = 0L, max_branch_expressions = 0L)

Arguments

max_branch_lines, max_branch_expressions

Integer, default 0 indicates "no maximum". If set any if/⁠else if⁠/.../⁠else⁠ chain where any branch occupies more than this number of lines (resp. expressions) will not be linted. The conjugate applies to switch() statements – if these parameters are set, any switch() statement with any overly-complicated branches will be linted. See examples.

Details

This can also be accomplished by repeated if/⁠else⁠ statements like so: if (x == "a") 1 else if (x == "b") 2 else if (x == "c") 7 else 8 (implicitly, the last ⁠else⁠ assumes x only takes 4 possible values), but this is more cluttered and slower (note that switch() takes the same time to evaluate regardless of the value of x, and is faster even when x takes the first value (here a), and that the if/⁠else⁠ approach is roughly linear in the number of conditions that need to be evaluated, here up to 3 times).

Tags

best_practices, configurable, consistency, efficiency, readability

See Also

linters for a complete list of linters available in lintr.

Examples

# will produce lints
lint(
  text = "if (x == 'a') 1 else if (x == 'b') 2 else 3",
  linters = if_switch_linter()
)

code <- paste(
  "if (x == 'a') {",
  "  1",
  "} else if (x == 'b') {",
  "  2",
  "} else if (x == 'c') {",
  "  y <- x",
  "  z <- sqrt(match(y, letters))",
  "  z",
  "}",
  sep = "\n"
)
writeLines(code)
lint(
  text = code,
  linters = if_switch_linter()
)

code <- paste(
  "if (x == 'a') {",
  "  1",
  "} else if (x == 'b') {",
  "  2",
  "} else if (x == 'c') {",
  "  y <- x",
  "  z <- sqrt(",
  "    match(y, letters)",
  "  )",
  "  z",
  "}",
  sep = "\n"
)
writeLines(code)
lint(
  text = code,
  linters = if_switch_linter()
)

code <- paste(
  "switch(x,",
  "  a = {",
  "    1",
  "    2",
  "    3",
  "  },",
  "  b = {",
  "    1",
  "    2",
  "  }",
  ")",
  sep = "\n"
)
writeLines(code)
lint(
  text = code,
  linters = if_switch_linter(max_branch_lines = 2L)
)

# okay
lint(
  text = "switch(x, a = 1, b = 2, 3)",
  linters = if_switch_linter()
)

# switch() version not as clear
lint(
  text = "if (x == 'a') 1 else if (x == 'b' & y == 2) 2 else 3",
  linters = if_switch_linter()
)

code <- paste(
  "if (x == 'a') {",
  "  1",
  "} else if (x == 'b') {",
  "  2",
  "} else if (x == 'c') {",
  "  y <- x",
  "  z <- sqrt(match(y, letters))",
  "  z",
  "}",
  sep = "\n"
)
writeLines(code)
lint(
  text = code,
  linters = if_switch_linter(max_branch_lines = 2L)
)

code <- paste(
  "if (x == 'a') {",
  "  1",
  "} else if (x == 'b') {",
  "  2",
  "} else if (x == 'c') {",
  "  y <- x",
  "  z <- sqrt(",
  "    match(y, letters)",
  "  )",
  "  z",
  "}",
  sep = "\n"
)
writeLines(code)
lint(
  text = code,
  linters = if_switch_linter(max_branch_expressions = 2L)
)

code <- paste(
  "switch(x,",
  "  a = {",
  "    1",
  "    2",
  "    3",
  "  },",
  "  b = {",
  "    1",
  "    2",
  "  }",
  ")",
  sep = "\n"
)
writeLines(code)
lint(
  text = code,
  linters = if_switch_linter(max_branch_lines = 3L)
)


r-lib/lintr documentation built on Dec. 20, 2024, 7:24 p.m.