array

Utility Methods for working with Arrays / Lists

similar to module:group, this is not meant to be exhaustive, only the ones commonly used.

Classes

PeekableArrayIterator

Members

(static) extract

See:

Convenience function for picking specific rows and columns from a 2d array.

Alias of array.pick

Please also see Danfo.js for working with DataFrames.

Example
data = [
 ['john', 23, 'purple'],
 ['jane', 32, 'red'],
 ['ringo', 27, 'green']
];

utils.array.pick(data, {rows: [0, 1]});
//-- [['john', 23, 'purple'], ['jane', 32, 'red']];

utils.array.pick(data, {columns: [0, 2]});
//-- [['john', 'purple'], ['jane', 'red'], ['ringo', 'green']];

utils.array.pick(data, {rows:[0, 1], columns:[0, 2]});
//-- [['john', 'purple'], ['jane', 'red']];

Methods

(static) SORT_ASCENDING()

Simple ascending sort function

Example
[3,5,1,2,4].sort(utils.sort.SIMPLE_ASCENDING))
//
[1,2,3,4,5]

(static) SORT_DESCENDING()

Simple descending sort function

Example
[3,5,1,2,4].sort(utils.sort.SIMPLE_ASCENDING))
//
[5,4,3,2,1]

(static) applyArrayValue(collection, path, value) → {Array}

See:

Applies deeply onto an array safely - in-place using dot-notation paths even if the child paths don't exist.

While tthis can be as simple as safely applying a value even if targetObj may be null

targetObj = [1, 2, null, 4, 5];

utils.object.applyPropertyValue(targetObj, '[2]', 3);
// [1, 2, 3, 4, 5]
// equivalent to targetObj[2] = 3;

This is much more safely working with deeply nested objects

targetObj = [{
 name: 'john smith',
 class: {
   name: 'ECON_101',
   professor: {
     last_name: 'Winklemeyer'
   }
  }
}];

utils.object.applyPropertyValue(targetObj, '[0].class.professor.first_name', 'René');
// [{
//  name: 'john smith',
//  class: {
//    name: 'ECON_101',
//    professor: {
//      last_name: 'Winklemeyer',
//      first_name: 'René' // <- Added
//    }
//   }
// }];

or creating intermediary objects along the path - if they did not exist first.

targetObj = [{
 name: 'john smith'
}];
utils.object.applyPropertyValue(targetObj, '[0].class.professor.first_name', 'René');
[{
 name: 'john smith',
 class: {
   professor: {
     first_name: 'René'
   }
  }
}];
Parameters:
Name Type Description
collection Array

array to apply the value to

path string

dot notation path to set the value, ex: 'geo', or 'states[0].prop'

value any

value to set

Returns:
  • the base array
Type
Array

(static) applyArrayValues(collection, path, value) → {Object}

See:

Converse from the extractPropertyValue, this takes a value / set of values and applies the values for each index in the collection.

for example:

weather = [{ id: 1, city: 'Seattle',  month: 'Aug', precip: 0.87 },
  { id: 3, city: 'New York', month: 'Apr', precip: 3.94 },
  { id: 6, city: 'Chicago',  month: 'Apr', precip: 3.62 }];

cities = utils.object.extractObjectProperty('city');
// ['Seattle', 'New York', 'Chicago'];

//-- async process to geocode
geocodedCities = geocodeCity(cities);
// [{ city: 'Seattle', state: 'WA', country: 'USA' },
// { city: 'New York', state: 'NY', country: 'USA' },
// { city: 'Chicago', state: 'IL', country: 'USA' }]

utils.applyArrayValues(weather, 'geo', geocodedCities);
// [{ id: 1, city: 'Seattle',  month: 'Aug', precip: 0.87, geo: { city: 'Seattle', state: 'WA', country: 'USA' } },
//  { id: 3, city: 'New York', month: 'Apr', precip: 3.94, geo: { city: 'New York', state: 'NY', country: 'USA' } },
//  { id: 6, city: 'Chicago',  month: 'Apr', precip: 3.62, geo: { city: 'Chicago', state: 'IL', country: 'USA' } }];

Note that traditional [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
works best for if you are working with objects completely in memory.

But this helps quite a bit if the action of mapping / transforming values
needs to be separate from the extraction / application of values back.
Parameters:
Name Type Description
collection Array

array to apply the value to on each index

path string

dot notation path to set the value within each index, ex: 'geo', or 'states[0].prop'

value any

the value that should be set at that path.

Returns:
Type
Object

(static) arrange(length, startopt, stepopt) → {Array.<Number>}

See:

Creates an array of values to replace for loops

Example
utils.array.arange(10, 1)
 .map((val) => `item ${val}`);
//
[
  'item 1', 'item 2',
  'item 3', 'item 4',
  'item 5', 'item 6',
  'item 7', 'item 8',
  'item 9', 'item 10'
]
Parameters:
Name Type Attributes Default Description
length Number

the number of items toreturn

start Number <optional>
0

the starting number

step Number <optional>
1

the number to increment for each step

Returns:
  • collection of numbers
Type
Array.<Number>

(static) arrangeMulti(…dimensions)

Creates an array for multiple dimensions of varying sizes.

(In order from higher order dimensions to lower)

utils.array.arangeMulti(0); // []
utils.array.arangeMulti(2); // [0, 1]
utils.array.arangeMulti(4); // [0, 1, 2, 3]
utils.array.arangeMulti(2, 2); // [[0, 1], [0, 1]]
utils.array.arangeMulti(2, 2, 2); // [[[0, 1], [0, 1]], [[0, 1], [0, 1]]]
utils.array.arangeMulti(2, 2, 4); // [[[0, 1, 2, 3], [0, 1, 2, 3]], [[0, 1, 2, 3], [0, 1, 2, 3]]]

Note that this can help with laying items out within a grid

gridPositions = utils.array.arangeMulti(4, 4)
  .reduce((result, row, rowIndex) => [ ...result,
     ...row.reduce((rowReduce, value, columnIndex) => [...rowReduce, [rowIndex, columnIndex]], [])
  ], []);
// [
//   [ 0, 0 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ],
//   [ 1, 0 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ],
//   [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ],
//   [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ]
// ]

myList.forEach((value, index) => {
  const [x, y] = gridPositions[index];
  console.log(`placing ${value} in row:${x}, column:${y}`);
});
Parameters:
Name Type Attributes Description
dimensions any <repeatable>

sizes of each dimension to create

Returns:

Multi-dimensional array

(static) asyncWaitAndChain(seconds, fn, rows) → {Promise.<any>}

See:
  • chainFunctions - to execute methods right after each other.
  • rxjs if you would like to execute more than one at a time.

Similar to chainFunctions - in that only one delayed function will occur at a time, but adds a delay between calls.

This also supports functions returning promises.

const sumValues = (...rest) => rest.reduce((result, val) => result + val, 0);

const arguments = [
 [1],
 [1, 1],
 [1, 1, 2],
 [1, 1, 2, 3]
];

utils.array.asyncWaitAndChain(3, sumValues, arguments)
 .then((results) => console.log(`fibonnacci numbers: ${results}`));
// fibonacci numbers: [1, 2, 4, 7], but took 9 seconds to accomplish
Parameters:
Name Type Description
seconds Number

number of seconds to delay between each execution

fn function

function to be called for each row of rows

rows Array.<Array.<any>>

Array where each row are arguments to be applied to fn

Returns:
  • promise that will resolve when the last delayed function finishes
Type
Promise.<any>

(static) chainFunctions(fn, rows) → {Promise.<any>}

See:
  • rxjs if you would like to have more than one active at a time.
  • asyncWaitAndChain - if you would like a delay between executions

Chain a set of functions to be called one after another (supports functions returning promises)

This is especially helpful if calls need to be rate limited to only having 1 occur at a time.

The resulting promise will return a list, with each entry corresponding with the row of arguments sent.

const sumValues = (...rest) => rest.reduce((result, val) => result + val, 0);

const arguments = [
 [1],
 [1, 1],
 [1, 1, 2],
 [1, 1, 2, 3]
];

utils.array.chainFunctions(sumValues, arguments)
 .then((results) => console.log(`fibonnacci numbers: ${results}`));
// fibonacci numbers: [1, 2, 4, 7]
Parameters:
Name Type Description
fn function

the function to be called

rows Array.<Array.<any>>

Array where each row are arguments to be applied to fn

Returns:
  • promise that will resolve when the last delayed function finishes
Type
Promise.<any>

(static) clone(target)

Deep clones multi-dimensional arrays.

If you want to just deep clone a 1d array, use [...target] instead

NOTE: this only deep clones Arrays, and not the values within the arrays.

const sourceArray = [[0, 1], [2, 3]];
const targetArray = utils.array.clone(sourceArray);

targetArray[0][0] = 99;

console.log(targetArray); // [[99, 1], [2, 3]];
console.log(sourceArray); // [[0, 1], [2, 3]];
Parameters:
Name Type Description
target any | Array

Array to be cloned

Returns:

New deep-cloned array

(static) createSort(fieldName) → {function}

Creates a sort function based on fields of an object.

sampleData = [{score: 200, name: 'jane'}, {score: 200, name: 'john'}]
// sort by score descending, and then by name ascending
sampleData.sort(utils.array.createSort('-score','name'))
Example
sampleData = [{i:4}, {v:2}, {v:1}, {v:3}];
sortedData = sampleData.sort(
   utils.createSort('-v')
);
// [{v:4}, {v:3}, {v:2}, {v:1}]
Parameters:
Name Type Description
fieldName String

name of property to sort by with - for descending

Returns:
Type
function

(static) delayedFn(fn, …rest) → {function}

See:

Defines a function and arguments that will only be called, only when the delayedFunction is called.

(Similar to Function.bind - but supports Function.call(1,2,3) or Function.apply([1,2,3]) syntax)

Example, these are equivalent, but the delayedFn does not mess with this

sayFn = (...rest) => console.log(...rest); arguments = [0, 1, 2, 3, 4, 5];

Spy(sayFn);

delayedFnA = sayFn.bind(globalThis, arguments); ... sayFn.calledCount; // 0 delayedFnA(); // consoles: [0, 1, 2, 3, 4, 5]; sayFn.calledCount; // 1

delayedFnB = utils.array.delayedFn(sayFn, 0, 1, 2, 3, 4, 5); ... delayedFnB(); // consoles: [0, 1, 2, 3, 4, 5];

Parameters:
Name Type Attributes Description
fn function

Function to be executed at a later time

rest any <repeatable>

arguments to be passed to fn

Returns:
  • function that can be called to execute fn with the arguments
Type
function

(static) extractFromHardSpacedTable(str, columnWidths) → {Array.<Array.<String>>}

Useful for extracting out hard spaced string arrays separated by newlines

hardSpacedString = `
id first_name last_name  city        email                        gender ip_address      airport_code car_model_year
-- ---------- ---------- ----------- ---------------------------- ------ --------------- ------------ --------------
1  Thekla     Brokenshaw Chicago     tbrokenshaw0@kickstarter.com Female 81.118.170.238  CXI          2003          
2  Lexi       Dugall     New York    ldugall1@fc2.com             Female 255.140.25.31   LBH          2005          
3  Shawna     Burghill   London      sburghill2@scribd.com        Female 149.240.166.189 GBA          2004          
4  Ginger     Tween      Lainqu      gtween3@wordpress.com        Female 132.67.225.203  EMS          1993          
5  Elbertina  Setford    Los Angeles esetford4@ted.com            Female 247.123.242.49  MEK          1989          `;

columns = [
  'id ',
  'first_name ',
  'last_name  ',
  'city        ',
  'email                        ',
  'gender ',
  'ip_address      ',
  'airport_code ',
  'car_model_year '
];
columnWidths = columns.map((str) => str.length);
// [ 3, 11, 11, 12, 29, 7, 16, 13, 15 ];


results = utils.array.extractFromHardSpacedTable(str, columnWidths);

[['id ', '-- ', '1  ', '2  ', '3  ', '4  ', '5  '],
['first_name ', '---------- ', 'Thekla     ', 'Lexi       ', 'Shawna     ', 'Gin...', ...],
['last_name  ', '---------- ', 'Brokenshaw ', 'Dugall     ', 'Burghill   ', 'Twe...', ...],
['city        ', '----------- ', 'Chicago     ', 'New York    ', 'London      ', ...],
['email                        ', '---------------------------- ', 'tbrokenshaw0...', ...],
['gender ', '------ ', 'Female ', 'Female ', 'Female ', 'Female ', 'Female '],
['ip_address      ', '--------------- ', '81.118.170.238  ', '255.140.25.31   ', ...],
['airport_code ', '------------ ', 'CXI          ', 'LBH          ', 'GBA       ...', ...],
['car_model_year', '--------------', '2003          ', '2005          ', '2004  ...', ...]]

We can then transpose the array to give us the format we might expect (non DataFrame centric)

resultsData = utils.array.transpose(results);

utils.table(resultsData).render();
0 1 2 3 4 5 6 7 8
id first_name last_name city email gender ip_address airport_code car_model_year
-- ---------- ---------- ----------- ---------------------------- ------ --------------- ------------ --------------
1 Thekla Brokenshaw Chicago tbrokenshaw0@kickstarter.com Female 81.118.170.238 CXI 2003
2 Lexi Dugall New York ldugall1@fc2.com Female 255.140.25.31 LBH 2005
3 Shawna Burghill London sburghill2@scribd.com Female 149.240.166.189 GBA 2004
4 Ginger Tween Lainqu gtween3@wordpress.com Female 132.67.225.203 EMS 1993
5 Elbertina Setford Los Angeles esetford4@ted.com Female 247.123.242.49 MEK 1989
Parameters:
Name Type Description
str String

Markdown / Hard Spaced Strings

columnWidths Array.<Number>

Array of of the column widths to extract

Returns:
  • Array of Arrays, where each row is an extracted column
Type
Array.<Array.<String>>

(static) indexify(source, …sectionIndicatorFunctions) → {Array.<Object>}

Create a unique number index for each element in an array, alternatively using additional functions to indicate hierarchies of data.

For example, markdown can be considered a hierarchy of data:

markdownList = `# Overview
This entire list is a hierarchy of data.

# Section A
This describes section A

## SubSection 1
With a subsection belonging to Section A

## SubSection 2
And another subsection sibling to SubSection 1, but also under Section A.

# Section B
With an entirely unrelated section B, that is sibling to Section A

## SubSection 1
And another subsection 1, but this time related to Section B.`;

And we want to convert this 1d array into a hierarchy.

data = markdownList.split('\n')
   .filter(line => line ? true : false); // check for empty lines

utils.format.consoleLines( data, 4);
// ['# Overview',
// 'This entire list is a hierarchy of data.',
// '# Section A',
// 'This describes section A',;

//-- functions that return True if we are in a new "group"
isHeader1 = (str) => str.startsWith('# ');

isHeader1('# Overview'); // true
isHeader1('This entire list is a hierarchy of data'); // false
isHeader1('# Section A'); // true
isHeader1('This describes section A'); // false

indexedData = utils.array.indexify(data, isHeader1);
[
  { entry: 'Heading', section: [ 0 ], subIndex: 1 },
  { entry: '# Overview', section: [ 1 ], subIndex: 0 },
  {
    entry: 'This entire list is a hierarchy of data.',
    section: [ 1 ],
    subIndex: 1
  },
  { entry: '# Section A', section: [ 2 ], subIndex: 0 },
  { entry: 'This describes section A', section: [ 2 ], subIndex: 1 },
  { entry: '## SubSection 1', section: [ 2 ], subIndex: 2 },
  {
    entry: 'With a subsection belonging to Section A',
    section: [ 2 ],
    subIndex: 3
  },
  { entry: '## SubSection 2', section: [ 2 ], subIndex: 4 },
  {
    entry: 'And another subsection sibling to SubSection 1, but also under Section A.',
    section: [ 2 ],
    subIndex: 5
  },
  { entry: '# Section B', section: [ 3 ], subIndex: 0 },
  {
    entry: 'With an entirely unrelated section B, that is sibling to Section A',
    section: [ 3 ],
    subIndex: 1
  },
  { entry: '## SubSection 1', section: [ 3 ], subIndex: 2 },
  {
    entry: 'And another subsection 1, but this time related to Section B.',
    section: [ 3 ],
    subIndex: 3
  }
];

Note that this only indexes elements by the first header.

To index this with two levels of hierarchy, we can pass another function.

isHeader2 = (str) => str.startsWith('## ');

isHeader2('# Overview'); // false
isHeader2('This entire list is a hierarchy of data'); // false
isHeader2('# Section A'); // true
isHeader2('This describes section A'); // false

indexedData = utils.array.indexify(data, isHeader1, isHeader2);
// [
//   { entry: 'Heading', section: [ 0, 0 ], subIndex: 1 },
//   { entry: '# Overview', section: [ 1, 0 ], subIndex: 0 },
//   {
//     entry: 'This entire list is a hierarchy of data.',
//     section: [ 1, 0 ],
//     subIndex: 1
//   },
//   { entry: '# Section A', section: [ 2, 0 ], subIndex: 0 },
//   { entry: 'This describes section A', section: [ 2, 0 ], subIndex: 1 },
//   { entry: '## SubSection 1', section: [ 2, 1 ], subIndex: 0 },
//   {
//     entry: 'With a subsection belonging to Section A',
//     section: [ 2, 1 ],
//     subIndex: 1
//   },
//   { entry: '## SubSection 2', section: [ 2, 2 ], subIndex: 0 },
//   {
//     entry: 'And another subsection sibling to SubSection 1, but also under Section A.',
//     section: [ 2, 2 ],
//     subIndex: 1
//   },
//   { entry: '# Section B', section: [ 3, 0 ], subIndex: 0 },
//   {
//     entry: 'With an entirely unrelated section B, that is sibling to Section A',
//     section: [ 3, 0 ],
//     subIndex: 1
//   },
//   { entry: '## SubSection 1', section: [ 3, 1 ], subIndex: 0 },
//   {
//     entry: 'And another subsection 1, but this time related to Section B.',
//     section: [ 3, 1 ],
//     subIndex: 1
//   }
// ];
Parameters:
Name Type Attributes Description
source Array

list of values to index

sectionIndicatorFunctions function <repeatable>

each function indicates a new section

Returns:
  • collection of objects, each with a new section (indicating the layers) and subIndex: unique value in the section (always 0 for header)
Type
Array.<Object>

(static) isMultiDimensional(targetArray) → {Boolean}

Determine whether an array is multi-dimensional (an array of arrays)

For example:

utils.array.isMultiDimensional(0); // false
utils.array.isMultiDimensional([0,1,2,3]); // false
utils.array.isMultiDimensional([[0,1], [2,3]]); // true
utils.array.isMultiDimensional([0, [1,2]]); // true
Parameters:
Name Type Description
targetArray Array

array to check if multi-dimensional

Returns:
  • if the targetArray has any values that are multi-dimensional
Type
Boolean

(static) multiLineSubstr(str, start, lenopt) → {Array.<String>}

See:

Parse a fixed length table of strings (often in markdown format)

This is different from multiLineSubString in this uses a start position and string length (not start and end position per line)

For example, say you got a string formatted like this:

hardSpacedString = `
id first_name last_name  city        email                        gender ip_address      airport_code car_model_year
-- ---------- ---------- ----------- ---------------------------- ------ --------------- ------------ --------------
1  Thekla     Brokenshaw Chicago     tbrokenshaw0@kickstarter.com Female 81.118.170.238  CXI          2003          
2  Lexi       Dugall     New York    ldugall1@fc2.com             Female 255.140.25.31   LBH          2005          
3  Shawna     Burghill   London      sburghill2@scribd.com        Female 149.240.166.189 GBA          2004          
4  Ginger     Tween      Lainqu      gtween3@wordpress.com        Female 132.67.225.203  EMS          1993          
5  Elbertina  Setford    Los Angeles esetford4@ted.com            Female 247.123.242.49  MEK          1989          `;

This can be a bit hard to parse, because the space delimiter is a valid character in the city column, ex: New York.

Instead, we can use the starting index and number of characters, to extract the data out

const carModelYears = ArrayUtils.multiLineSubstr(hardSpacedString, 102);
// ['car_model_year', '--------------', '2003          ', '2005          ', '2004          ', '1993          ', '1989'];
const ipAddresses = ArrayUtils.multiLineSubstr(hardSpacedString, 73, 14);
// ['ip_address    ', '--------------', '81.118.170.238', '255.140.25.31 ', '149.240.166.18', '132.67.225.203', '247.123.242.49'];
Parameters:
Name Type Attributes Default Description
str String | Array.<String>

multi-line string or array of strings

start Number

the starting index to substr

len Number <optional>
0

optional length of string to substr

Returns:
  • substr values from each line
Type
Array.<String>

(static) multiLineSubstring(str, startPosition, endPositionopt) → {Array.<String>}

See:

Parse a fixed length table of strings (often in markdown format)

This is different from multiLineSubStr in this uses a start and end position (not start and length)

For example, say you got a string formatted like this:

hardSpacedString = `
id first_name last_name  city        email                        gender ip_address      airport_code car_model_year
-- ---------- ---------- ----------- ---------------------------- ------ --------------- ------------ --------------
1  Thekla     Brokenshaw Chicago     tbrokenshaw0@kickstarter.com Female 81.118.170.238  CXI          2003          
2  Lexi       Dugall     New York    ldugall1@fc2.com             Female 255.140.25.31   LBH          2005          
3  Shawna     Burghill   London      sburghill2@scribd.com        Female 149.240.166.189 GBA          2004          
4  Ginger     Tween      Lainqu      gtween3@wordpress.com        Female 132.67.225.203  EMS          1993          
5  Elbertina  Setford    Los Angeles esetford4@ted.com            Female 247.123.242.49  MEK          1989          `;

This can be a bit hard to parse, because the space delimiter is a valid character in the city column, ex: New York.

Instead, we can use the starting index and number of characters, to extract the data out.

Note, this function uses the starting and ending character positions, to extract, where multiLineSubstr - uses the start and character length instead.

const carModelYears = ArrayUtils.multiLineSubstring(hardSpacedString, 102);
// ['car_model_year', '--------------', '2003          ', '2005          ', '2004          ', '1993          ', '1989'];
const ipAddresses = ArrayUtils.multiLineSubstring(hardSpacedString, 73, 87);
// ['ip_address    ', '--------------', '81.118.170.238', '255.140.25.31 ', '149.240.166.18', '132.67.225.203', '247.123.242.49'];
Parameters:
Name Type Attributes Description
str String | Array.<String>

multi-line string or array of strings

startPosition Number

the starting index to extract out - using the standard substring method

endPosition Number <optional>

the ending endex to extract out

Returns:
  • substr values from each line
Type
Array.<String>

(static) multiStepReduce()

Returns the reduce at each step along the way.

For example, if you have a set of column widths and would like to know how wide the table is after each column.

For example:

hardSpacedString = `
id first_name last_name  city        email                        gender ip_address      airport_code car_model_year
-- ---------- ---------- ----------- ---------------------------- ------ --------------- ------------ --------------
1  Thekla     Brokenshaw Chicago     tbrokenshaw0@kickstarter.com Female 81.118.170.238  CXI          2003          
2  Lexi       Dugall     New York    ldugall1@fc2.com             Female 255.140.25.31   LBH          2005          
3  Shawna     Burghill   London      sburghill2@scribd.com        Female 149.240.166.189 GBA          2004          
4  Ginger     Tween      Lainqu      gtween3@wordpress.com        Female 132.67.225.203  EMS          1993          
5  Elbertina  Setford    Los Angeles esetford4@ted.com            Female 247.123.242.49  MEK          1989          `;

columns = [
  'id ',
  'first_name ',
  'last_name  ',
  'city        ',
  'email                        ',
  'gender ',
  'ip_address      ',
  'airport_code ',
  'car_model_year '
];
columnWidths = columns.map((str) => str.length);
// [ 3, 11, 11, 12, 29, 7, 16, 13, 15 ];

//-- get the starting position for each column,
//-- ex: column 3 is sum of columnWidths[0..3] or 0 + 3 + 11 + 11 or 25
columnStops = utils.array.multiStepReduce( columnWidths, (a,b) => a + b, 0);
// [0, 3, 14, 25, 37, 66, 73, 89, 102, 117];

We can then pair with the column widths - to get exactly the starting position and width of each column.

substrPairs = columnWidths.map((value, index) => [columnStops[index], value]);
// [[0, 3], [3, 11], [14, 11], [25, 12], [37, 29], [66, 7], [73, 16], [89, 13], [102, 15]];

Now that we know how the starting positions for each of the columns, we can try picking one column out:

//-- we can get a single column like this:
cityStartingCharacter = substrPairs[3][0]; // 25
cityColumnLength = substrPairs[3][1]; // 12

cityData = ArrayUtils.multiLineSubstr(hardSpacedString, cityStartingCharacter, cityColumnLength);
// ['city        ', '----------- ', 'Chicago     ', 'New York    ', 'London      ', 'Lainqu      ', 'Los Angeles ']

Or we can get all columns with something like this:

results = substrPairs.map(
 ([startingPos, length]) => ArrayUtils.multiLineSubstr(hardSpacedString, startingPos, length)
);

[['id ', '-- ', '1  ', '2  ', '3  ', '4  ', '5  '],
['first_name ', '---------- ', 'Thekla     ', 'Lexi       ', 'Shawna     ', 'Gin...', ...],
['last_name  ', '---------- ', 'Brokenshaw ', 'Dugall     ', 'Burghill   ', 'Twe...', ...],
['city        ', '----------- ', 'Chicago     ', 'New York    ', 'London      ', ...],
['email                        ', '---------------------------- ', 'tbrokenshaw0...', ...],
['gender ', '------ ', 'Female ', 'Female ', 'Female ', 'Female ', 'Female '],
['ip_address      ', '--------------- ', '81.118.170.238  ', '255.140.25.31   ', ...],
['airport_code ', '------------ ', 'CXI          ', 'LBH          ', 'GBA       ...', ...],
['car_model_year', '--------------', '2003          ', '2005          ', '2004  ...', ...]]

We can then transpose the array to give us the format we might expect (non DataFrame centric)

resultsData = utils.array.transpose(results);

utils.table(resultsData).render();
0 1 2 3 4 5 6 7 8
id first_name last_name city email gender ip_address airport_code car_model_year
-- ---------- ---------- ----------- ---------------------------- ------ --------------- ------------ --------------
1 Thekla Brokenshaw Chicago tbrokenshaw0@kickstarter.com Female 81.118.170.238 CXI 2003
2 Lexi Dugall New York ldugall1@fc2.com Female 255.140.25.31 LBH 2005
3 Shawna Burghill London sburghill2@scribd.com Female 149.240.166.189 GBA 2004
4 Ginger Tween Lainqu gtween3@wordpress.com Female 132.67.225.203 EMS 1993
5 Elbertina Setford Los Angeles esetford4@ted.com Female 247.123.242.49 MEK 1989

This can also be helpful with coming up with complex array.arrange(size, start, step) collections.

(static) peekFirst(targetArray, defaultVal) → {any}

Peek in an array and return the first value in the array.

Or return the default value (defaultVal) - if the array is empty

Parameters:
Name Type Description
targetArray Array

array to be peeked within

defaultVal any

the value to return if the array is empty

Returns:
Type
any

(static) peekLast(targetArray, defaultVal) → {any}

Peek in an array and return the last value in the array.

Or return the default value (defaultVal) - if the array is empty

Parameters:
Name Type Description
targetArray Array

array to be peeked within

defaultVal any

the value to return if the array is empty

Returns:
Type
any

(static) pick(array2d, options) → {Array}

See:

Convenience function for picking specific rows and columns from a 2d array.

Please also see Danfo.js for working with DataFrames.

Example
data = [
 ['john', 23, 'purple'],
 ['jane', 32, 'red'],
 ['ringo', 27, 'green']
];

utils.array.pick(data, {rows: [0, 1]});
//-- [['john', 23, 'purple'], ['jane', 32, 'red']];

utils.array.pick(data, {columns: [0, 2]});
//-- [['john', 'purple'], ['jane', 'red'], ['ringo', 'green']];

utils.array.pick(data, {rows:[0, 1], columns:[0, 2]});
//-- [['john', 'purple'], ['jane', 'red']];
Parameters:
Name Type Description
array2d Array

2d array to pick from [row][column]

options Object

options on which to pick

Properties
Name Type Attributes Default Description
rows Array.<Number> <optional>
null

indices of the rows to pick

columns Array.<Number> <optional>
null

indices of the columns to pick.

Returns:
    • 2d array of only the rows and columns chosen.
    Type
    Array
    • 2dArray of the columns and rows requested

(static) pickColumns(array2d, …columns)

See:

Picks a column (or multiple columns) from a 2d array

Please also see Danfo.js for working with DataFrames.

Example
data = [
 ['john', 23, 'purple'],
 ['jane', 32, 'red'],
 ['ringo', 27, 'green']
];

utils.array.pickColumns(data, 0);
//-- [['john'], ['jane'], ['ringo']];

utils.array.pickColumns(data, 0, 2);
//-- [['john', 'purple'], ['jane', 'red'], ['ringo', 'green']];
Parameters:
Name Type Attributes Description
array2d Array

2d array to pick from [row][column]

columns any <repeatable>

Indexes of the columns to pick the values from: [0...row.length-1]

Returns:
  • Array with all rows, and only those columns

(static) pickRows(array2d, …rowIndices)

See:

Picks a row (or multiple rows) from a 2d array.

Please also see Danfo.js for working with DataFrames.

Example
data = [
 ['john', 23, 'purple'],
 ['jane', 32, 'red'],
 ['ringo', 27, 'green']
];

utils.array.pickRows(data, 0);
//-- [['john', 23, 'purple']];

utils.array.pickRows(data, 0, 1);
//-- [['john', 23, 'purple'], ['jane', 32, 'red']];
Parameters:
Name Type Attributes Description
array2d Array

2d array to pick from [row][column]

rowIndices Number <repeatable>

Indexes of the row to return, [0...length-1]

Returns:
  • Array with only those rows

(static) reshape(sourceArray, numColumns) → {Array.<Array.<any>>}

Resizes an NxM dimensional array by number of columns

Example
baseArray = utils.array.arrange(12);
[
   0,  1, 2, 3, 4, 5,  6, 7, 8, 9, 10, 11
]

//-- resize the 1d array based on 3 columns
newArray = utils.array.reshape(baseArray, 3)
[ [ 0, 1, 2 ],
  [ 3, 4, 5 ],
  [ 6, 7, 8 ],
  [ 9, 10, 11 ] ];

//-- now resize the 4x3 array to 3x4
utils.array.reshape(newArray, 4);
[ [ 0, 1, 2, 3 ],
  [ 4, 5, 6, 7 ],
  [ 8, 9, 10, 11 ] ]
Parameters:
Name Type Description
sourceArray Array.<any>

an array to resize

numColumns Number

number of columns

Returns:
  • 2 dimensinal array
Type
Array.<Array.<any>>

(static) size(length, defaultValue) → {Array}

See:

Creates an array of a specific size and default value

Especially useful for forLoops, map or reduce

Example
utils.array.size(3, null)
 .map((v, index) => `item ${index}`)
Parameters:
Name Type Description
length Number

the length of the new array

defaultValue any

the new value to put in each cell

Returns:
  • an array of length size with default values
Type
Array

(static) transpose(matrix) → {Array.<any>}

Transposes a two dimensional array, so an NxM becomes MxN

Example
baseArray = [ 0, 1, 2, 3, 4 ];
utils.array.transpose(utils.array.arrange(5))
//
[ [ 0 ],
  [ 1 ],
  [ 2 ],
  [ 3 ],
  [ 4 ] ]
Parameters:
Name Type Description
matrix Array.<any>

MxN array

Returns:
  • NxM array
Type
Array.<any>