{
  "category": "Lookup and reference functions",
  "display_name": "CHOOSECOLS",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.CHOOSECOLS",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 17 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 17 recorded answers",
    "workbook_corpus": {
      "cells": 17,
      "matched": 17
    }
  },
  "implementations": [
    {
      "commit": "9e1884369a678158dd82d3d74188daf986995e87",
      "flavour": "excel-compatibility-candidate",
      "language": "Rust",
      "name": "CalcFunc",
      "own_code": [
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/arrays.rs#L663-L665",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/dynamic_array_reshape_family.rs#L298-L315"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/arrays::source_error",
        "catalogue/arrays::prepared",
        "catalogue/arrays::prepared_one",
        "catalogue/arrays::result",
        "catalogue/arrays::choose",
        "catalogue/arrays::as_array",
        "ported/dynamic_array_reshape_family::coerce_prepared_to_number",
        "ported/dynamic_array_reshape_family::scalar_cell",
        "ported/dynamic_array_reshape_family::materialize_array_arg",
        "ported/dynamic_array_reshape_family::shape",
        "ported/dynamic_array_reshape_family::get",
        "ported/dynamic_array_reshape_family::parse_integer",
        "ported/dynamic_array_reshape_family::resolve_selector",
        "ported/dynamic_array_reshape_family::build_array",
        "ported/dynamic_array_reshape_family::map_dynamic_array_reshape_error_to_ws"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/arrays.rs#L663-L665",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 17 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.CHOOSECOLS.json",
  "name": "CHOOSECOLS",
  "notes": [],
  "schema": "efh.function-reference/v1",
  "section_order": [
    "what-it-does",
    "try-it",
    "quirks",
    "how-to-implement",
    "version-differences",
    "alternatives"
  ],
  "sections": {
    "alternatives": "\n### Relationships\n\n- **`CHOOSEROWS`** is the same function on the other axis, with the same negative-index rule and\n  the same error condition. The pair is symmetric by construction.\n- **`TAKE` and `DROP`** select a *contiguous* block from an edge. `CHOOSECOLS` selects an\n  arbitrary list. If your selection is \"the first three columns\", `TAKE` says it more directly\n  and does not require you to enumerate.\n- **`HSTACK`** is the inverse operation in spirit: `CHOOSECOLS` splits columns out of one array,\n  `HSTACK` joins columns from several.\n- **`FILTER`** selects along an axis too, but by predicate rather than by index, and it filters\n  rows or columns according to the shape of its `include` argument.\n- **`CHOOSE`** shares a prefix and is unrelated: it selects among *arguments*, not among columns\n  of an array.\n\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n\n- **Output width is the index count, not the distinct-index count.** Any implementation that\n  deduplicates or sorts the index list silently changes the answer. This is the easiest bug to\n  write and the hardest to notice, because the common case has distinct ascending indices.\n- **Negative indices must be resolved against the input width before bounds checking**, and the\n  bounds check must reject zero. The three cases — positive, negative, zero — are one branch\n  each; folding zero into either sign's path produces an off-by-one.\n- **The whole family shares one module** in the reference implementation\n  (`dynamic_array_reshape_family.rs`, shared with `CHOOSEROWS`, `DROP`, `EXPAND`, `FILTER`,\n  `SORT`, `SORTBY`, `TAKE`, `TOCOL`, `TOROW`, `TRANSPOSE`, `UNIQUE`, `VSTACK`, `WRAPCOLS`,\n  `WRAPROWS`). Shared code means a shared shape-and-bounds discipline, and it means a test that\n  passes here may be exercising machinery the sibling functions also depend on.\n- **Empty results are not representable.** There is no zero-column array in the value model, so\n  a selection that yields nothing has to become an error rather than an empty result. That is\n  the structural reason the zero index is an error rather than a no-op.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturn kind: `Array`, of shape (rows of `array`) × (number of index values). The result spills\nin dynamic-array Excel; the shared spill and adaptation rules are the host-side concern\ndescribed in [the call pipeline](../model/03-call-pipeline.md), not function semantics.\n\n- **A scalar or 1×1 `array`.** One column exists, so `CHOOSECOLS(x, 1)` is defined; anything\n  else is out of range.\n- **A reference argument.** `array` is prepared under `ValuesOnlyPreAdapter`: the reference is\n  resolved to values before the function runs, so the result is an array of values and carries\n  no reference structure. Consequently `CHOOSECOLS` cannot be used where a reference is\n  required.\n- **Mixed types.** No coercion is applied to the selected elements; text, logicals and errors\n  pass through as themselves.\n\n\n\n### Errors\n\n\nMicrosoft's page documents the error condition directly: `CHOOSECOLS` returns `#VALUE!` if any\n`col_num` argument is zero or exceeds the number of columns in `array`. By the symmetry of the\ndocumented negative indexing, an index more negative than the column count is out of range on\nthe same rule.\n\nBeyond that, an error value supplied as an *argument* (rather than sitting inside the array)\npropagates under the universal rule in\n[coercion and lifting](../model/02-coercion-and-lifting.md).\n\nWhether a fractional index is truncated or rejected is not established here.\n\n\n",
    "sources": "\n- Microsoft, CHOOSECOLS function —\n  <https://support.microsoft.com/en-us/office/choosecols-function-bf117976-2722-4466-9b9a-1c01ed9aebff>\n  (column selection semantics, negative indexing from the end, and the `#VALUE!` condition for\n  zero or out-of-range indices).\n- Handbook `content/model/01-value-universe.md` (array kind; errors as values).\n- Handbook `content/model/02-coercion-and-lifting.md` (error propagation at the argument\n  boundary).\n- Handbook `content/model/03-call-pipeline.md` (`ValuesOnlyPreAdapter`; host-side spill\n  adaptation).\n- Handbook `data/functions/FUNC.CHOOSECOLS.json` and `data/presence/FUNC.CHOOSECOLS.json`\n  (arity, classification axes, the shared reshape-family module).\n\n",
    "version-differences": "No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.",
    "what-it-does": "Three properties follow from \"in the order given\" and are the reason the function exists at all:\n\n1. **It reorders.** `CHOOSECOLS(A, 3, 1, 2)` is a column permutation.\n2. **It duplicates.** An index may repeat; `CHOOSECOLS(A, 1, 1)` yields a two-column array whose\n   columns are equal. The output column count is the number of indices, not the number of\n   distinct indices.\n3. **It projects to fewer or more columns than the input has.** Fewer by omission, more by\n   repetition.\n\nRow count is invariant: the result has exactly as many rows as `array`. Only the column axis is\ntouched.\n\nIndices are one-based, and Microsoft documents that a **negative index counts from the end** of\nthe array — `-1` is the last column, `-2` the second to last. There is no zero index; zero is an\nerror, which is the natural consequence of one-based counting from both ends.\n\n\n\n### Arguments\n\n\n| Argument | Meaning |\n|---|---|\n| `array` | The array or range whose columns are to be selected. Required. |\n| `col_num1` | The first column to return. One-based; negative counts from the last column. Required. |\n| `col_num2`, … | Further columns, in output order. Optional, up to the arity ceiling of 255 arguments. |\n\nAn index argument may itself be an array — `CHOOSECOLS(A, {1,3,5})` — which is how you select a\ncomputed set of columns without writing them out. The interaction between an array-valued index\nargument and several index arguments (`CHOOSECOLS(A, {1,2}, 4)`) is a shape question the\nHandbook has not settled.\n\nThe position readers misjudge is the *first*: `array` is a single argument, so a multi-area\nreference or a comma-separated list of ranges does not work here the way it does for `HSTACK`.\nIf you want to combine several sources and then select, stack first, select second.\n\n\n"
  },
  "signature": {
    "display": "CHOOSECOLS(array, col_num1, [col_num2], ...)",
    "parameters": [
      {
        "description": null,
        "name": "array",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "col_num1",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "col_num2",
        "optional": true,
        "repeats": true
      }
    ],
    "trailing_repeats": true
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 255,
        "min": 2
      },
      "category": "Lookup and reference functions",
      "classification": {
        "arg_preparation_profile": "ValuesOnlyPreAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "Deterministic",
        "error_collapse_profile": "None",
        "fec_dependency_profile": "None",
        "host_interaction_class": "None",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "Selected columns of an array, in the order asked for",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the specified columns from an array",
        "microsoft_url": "https://support.microsoft.com/en-us/office/choosecols-function-bf117976-2722-4466-9b9a-1c01ed9aebff"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "bg-BG",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "cs-CZ",
          "name": "ZVOLITSLOUPCE"
        },
        {
          "locale": "da-DK",
          "name": "VÆLGKOL"
        },
        {
          "locale": "de-DE",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "el-GR",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "en-AU",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "en-GB",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "en-US",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "es-ES",
          "name": "ELEGIRCOLS"
        },
        {
          "locale": "et-EE",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "fi-FI",
          "name": "VALITSESARAKKEET"
        },
        {
          "locale": "fr-FR",
          "name": "CHOISIRCOLS*"
        },
        {
          "locale": "he-IL",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "hr-HR",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "hu-HU",
          "name": "OSZLOPVÁLASZTÁS"
        },
        {
          "locale": "id-ID",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "it-IT",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "ja-JP",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "ko-KR",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "lt-LT",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "lv-LV",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "nb-NO",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "nl-NL",
          "name": "KIES.KOLOMMEN"
        },
        {
          "locale": "pl-PL",
          "name": "WYBIERZ.KOLUMNY"
        },
        {
          "locale": "pt-BR",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "pt-PT",
          "name": "ESCOLHERCOLS"
        },
        {
          "locale": "ro-RO",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "ru-RU",
          "name": "ВЫБОРСТОЛБЦ"
        },
        {
          "locale": "sk-SK",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "sl-SI",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "sv-SE",
          "name": "VÄLJKOL"
        },
        {
          "locale": "th-TH",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "tr-TR",
          "name": "SÜTUNSEÇ"
        },
        {
          "locale": "uk-UA",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "vi-VN",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "zh-CN",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "zh-HK",
          "name": "CHOOSECOLS"
        },
        {
          "locale": "zh-TW",
          "name": "CHOOSECOLS"
        }
      ],
      "signature": {
        "display": "CHOOSECOLS(array, col_num1, [col_num2], ...)",
        "parameters": [
          {
            "description": null,
            "name": "array",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "col_num1",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "col_num2",
            "optional": true,
            "repeats": true
          }
        ],
        "trailing_repeats": true
      },
      "surface_name": "CHOOSECOLS",
      "version_marker": null,
      "xlcall": null
    },
    "microsoft": "https://support.microsoft.com/en-us/office/choosecols-function-bf117976-2722-4466-9b9a-1c01ed9aebff"
  },
  "try_it": {
    "formula": "=CHOOSECOLS({1,2;3,4},2)"
  },
  "url": "https://handbook.dnacalc.com/functions/CHOOSECOLS.html",
  "variants": [],
  "versions": []
}