lib_2da function library

Dependencies: lib_anon, lib_array, lib_fn, lib_ini, lib_sfo, lib_struct, lib_sugar, lib_tools

Description

Files for manipulating 2d arrays via their (assumed uppercase) rows and columns. The main use case is reading these 2d arrays out of .2da game files and extracting data from them, and/or manipulating them and writing them back in. This is (hopefully) a much simpler and more transparent way to manipulate 2das than by READ_2DA_ENTRY and friends.

Functions here should engage with the general 2da format and shouldn't refer to specific features of particular game's 2das. They should start with "2da_".

This library can handle these file formats:

  1. Standard, legally-formatted 2da files.
  2. IDS files, which are read in with an added set of row headers which are integers labelled from 0, and with columns 'int' and 'symbol'.
  3. Tables with column headers, which are read in with an added set of row headers as for IDS files.

Functions

2da_clone_column(silent:b, array:a, clone_to:s, location:s, clone_from:s)=(array:a) dimorphic

Given a 2d array, a column label 'clone_from', and a new column label 'clone_to', insert a copy of the clone_from column with the clone_to label, in the position specified by 'location'. 'location' can be 'first' (or 'start'), 'last' (or 'end'), 'before column_label' or 'after column_label'. If we can't find the column label, we default to 'last' (and whine about it unless silent=1).

2da_clone_row(silent:b, array:a, clone_to:s, location:s, clone_from:s)=(array:a) dimorphic

Given a 2d array, a row label 'clone_from', and a new row label 'clone_to', insert a copy of the clone_from row with the clone_to label, in the position specified by 'location'. 'location' can be 'first' (or 'start'), 'last' (or 'end'), 'before row_label' or 'after row_label'. If we can't find the row label, we default to 'last' (and whine about it unless silent=1).

2da_column_to_array(silent:b, column:s, array:a)=(array_out:a) dimorphic

Given a 2d array and column label 'column', extract that column as a 1d array indexed by the row labels.

If we can't find the column label, we return an empty array (and whine about it unless silent=1).

2da_delete_column(array:a, column:s)=(array:a) dimorphic

Given a 2d array, and column label 'column', delete that column.

2da_delete_row(array:a, row:s, lookup_column:s)=(array:a) dimorphic

Given a 2d array, and row label 'row', delete that row.

2da_extract_array(silent:b, domain:s, range:s, array:a, keymap:f, map:f, case:[upper|lower|mixed])=(array:a) dimorphic

Given a 2d array, and column labels 'domain' and 'range' for that array, return a 1d array whose keys are the elements of the 'domain' column and whose values are the elements of the 'range' column.

If you leave either 'domain' or 'range' empty, the row headers are used instead. If we can't find domain or range, we return an empty array (and whine unless silent=1).

Optionally, you can specify functions 'keymap' and/or 'map', which are applied to the keys and values respectively before being put into the output array. You can use the anonymous function construct.

2da_inject_array(silent:b, array:a, array_in:a, column:s)=(array:a) dimorphic

Given a 2d array, a column header of that array, and a k=>v array whose keys are row headers in the 2d array, inject the array elements into the 2d array, as (k=>v) goes to (k,col,v)

2da_insert_column(silent:b, array:a, column:s, location:s, entry:s="-1")=(array:a) dimorphic

Given a 2d array, and a column label, insert a new column with that column label in the position specified by 'location'. 'location' can be 'first' (or 'start'), 'last' (or 'end'), 'before column_label' or 'after column_label'. If we can't find the column label, we default to 'last' (and whine about it unless silent=1).

The new rows are filled with 'entry'.

2da_insert_row(silent:b, array:a, row:s, location:s, entry:s="-1")=(array:a) dimorphic

Given a 2d array, and a row label, insert a new row with that row label in the position specified by 'location'. 'location' can be 'first' (or 'start'), 'last' (or 'end'), 'before row_label' or 'after row_label'. If we can't find the row label, we default to 'last' (and whine about it unless silent=1).

The new rows are filled with 'entry'.

2da_make(rows:a, columns:a, fill:s="*")=(array:a) dimorphic

Given two arrays in k=>_ format, make a 2da with each character filled with some fixed data

2da_read(silent:b, reflect:b, allow_incomplete_lines:b, type:[2da|ids|table_header|table_no_header], rowmap:f, colmap:f, rowname_column:s, case:[upper|lower|mixed])=(columns:a, rows:a, array:a) patch
2da_read(silent:b, inline:b, reflect:b, allow_incomplete_lines:b, file:s, case:[upper|lower|mixed], path:s, type:s, location:s, locbase:s, rowmap:f, colmap:f, rowname_column:s)=(value:s, columns:a, rows:a, array:a) action

Read a 2da file (or, in patch context, the current 2da file) into a 2d array, with row and column keys uppercased. Also return an array of uppercased row headers and column headers, in the format row_label=>row_number. ('case' controls the case of the row and column headers; it's uppercase by default on genuine 2das, mixed by default otherwise)

If you don't specify a path for the 2da file, it's assumed to be a game file.

In action context, if the file doesn't exist return 0; otherwise, return 1. Also whine if it doesn't exist, unless silent=1.

If the file is a 2da, and 'reflect' is set, reverse rows and columns. If it's a 2da, and 'allow_incomplete_lines' is set, don't require that all lines are complete. If it's a 2da, and "rowname_column" is set, use that column (if it's present) for the row names instead of the usual entries.

2da_renumber(start_at:i, array:a)=(array:a) dimorphic

Given a 2d array, replace its row labels with sequential integers starting at 'start_at' (i.e. 0 by default)

2da_row_to_array(silent:b, row:s, array:a)=(array_out:a) dimorphic

Given a 2d array and row label 'row', extract that row as a 1d array indexed by the column labels.

If we can't find the row label, we return an empty array (and whine about it unless silent=1).

2da_to_3da(column1:s, column2:s, array:a)=(array_out:a) dimorphic

Given a 2d array and two column headers, extract a 3d array where the first two keys are the values in the new columns and the third is the old column header.

e.g. if row 14 has col1=x, col2=y, then 3da(x,y,z)=2da(14,z).

2da_write(reflect:b, number_rows:b, array:a, type:[2da|ids|table_header|table_noheader], default:s)=() patch
2da_write(number_rows:b, reflect:b, file:s, path:s, location:s, locbase:s, type:[2da|ids|table_header|table_noheader], array:a)=() action

Read a 2d array into a 2da file (or, in patch context, the current 2da file).

If you don't specify a path for the 2da file, it's assumed to be a game file.

If 'number_rows' is set to 1, the row names are replaced by integers, counting upwards from 0. If 'reflect' is set to 1, rows and columns are swapped.