object

Utility for working with and massaging javascript objects.

Members

(static) MAX_COLLAPSE_DEPTH :Number

See:

The maximum depth that a collapse will go to

Type:
  • Number

Methods

(static) applyPropertyValue(obj, path, value) → {Object}

See:

Applies a target value onto a source object in-place safely - using dot-notation paths.

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

targetObj = { id: 1, city: 'Seattle',  month: 'Aug', precip: 0.87 };
utils.object.applyPropertyValue(targetObj, 'state', 'WA');
// { id: 1, city: 'Seattle',  month: 'Aug', precip: 0.87, state: 'WA };

working with deeply nested objects

targetObj = { name: 'john smith', class: { name: 'ECON_101', professor: { last_name: 'Winklemeyer' }} };
utils.object.applyPropertyValue(targetObj, 'class.professor.first_name', 'René');
// { name: 'john smith', class: { name: 'ECON_101', professor: { last_name: 'Winklemeyer', first_name: 'René' }} };

or safely working with arrays of values

targetObj = { name: 'john smith', classes: [{ name: 'ECON_101' }] };
utils.object.applyPropertyValue(targetObj, 'classes[0].grade', 'A');
// { name: 'john smith', classes: [{ name: 'ECON_101', grade: 'A' }] };
Parameters:
Name Type Description
obj Object

object 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 object the value was applied to
Type
Object

(static) applyPropertyValues(obj, path, value) → {Object}

See:

Opposite of the extractObjectProperty, this takes a value / set of values and applies them along a given path on each of the target objects.

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.applyPropertyValues(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
obj Object

object to apply the value to

path string

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

value any

the value that should be set at that path.

Returns:
Type
Object

(static) assign(objopt, propertyName, value) → {Object}

Assign a property to an object and return object (allowing for functional programming assignments)

Example
objAssign({}, 'name', 'john').name === 'john'
Parameters:
Name Type Attributes Default Description
obj Object <optional>
{}

object to assign the value to (or null for a new one)

propertyName String
value any
Returns:
Type
Object

(static) assignEntities(objopt, entities) → {Object}

Assigns multiple object entities [[property, value], [property, value], ...];

Parameters:
Name Type Attributes Default Description
obj Object <optional>
{}

object to assign the values to

entities Array

2d array [[property, value], ...]

Returns:
Type
Object

(static) augment(objCollection, mappingFn, inPlaceopt) → {Array.<Object>}

Runs a map over a collection, and adds properties the the objects.

Example
data = [{ source: 'A', value: 5 }, { source: 'B', value: 11 },
       { source: 'A', value: 6 }, { source: 'B', value: 13 },
       { source: 'A', value: 5 }, { source: 'B', value: 12 }];
utils.object.augment(data, (record) => ({ origin: 's_' + record.source }));
// returns
[{ source: 'A', value: 5, origin: 's_A' }, { source: 'B', value: 11, origin: 's_B' },
 { source: 'A', value: 6, origin: 's_A' }, { source: 'B', value: 13, origin: 's_B' },
 { source: 'A', value: 5, origin: 's_A' }, { source: 'B', value: 12, origin: 's_B' }];

// by default `inPlace = false`, and data is not updated
data[0] // { source: 'A', value: 5 }

// if `inPlace = true`, then data would be updated
data[0] // { source: 'A', value: 5, origin: 's_A' }
Parameters:
Name Type Attributes Default Description
objCollection Object | Array.<Object>

object or collection of objects to augment

mappingFn function | Object

(record) => {Object} mapping function
or object with properties to create

inPlace Boolean <optional>
false

whether to update the collection in place (true) or cloned (false)

Returns:
  • collection of records with the fields merged
Type
Array.<Object>

(static) augmentInherit(source, augmentFn) → {Array.<Object>}

See:

Appends values to a collection of objects, where if the value undefined is provided, then it "remembers" or "inherits" the value previously used.

This is VERY useful for converting a 1 dimensional list, into a hierarchical tree structure.

For example, say we got this from a previous successful scrape:

source = [
  { text: '# Overview' },
  { text: 'This entire list is a hierarchy of data.' },
  { text: '# Section A' },
  { text: 'This describes section A' },
  { text: '## SubSection 1' },
  { text: 'With a subsection belonging to Section A' },
  { text: '# Section B' },
  { text: 'With an entirely unrelated section B, that is sibling to Section A' }
];

We would like to know which heading1 and heading2 the texts belong to:


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

//-- note, return undefined for any property you don't want to have inherited.
inheritFn = (entry) => ({
  section: isHeader1(entry.text) ? entry.text.replace(/#+\s+/, '') : undefined,
  subSection: isHeader2(entry.text) ? entry.text.replace(/#+\s+/, '') : undefined
});

results = utils.object.augmentInherit(source, inheritFn);
text section subSection
Overview Overview undefined
This entire list is a hierarchy of data. Overview undefined
Section A Section A undefined
This describes section A Section A undefined
SubSection 1 Section A SubSection 1
With a subsection belonging to Section A Section A SubSection 1
Section B Section B undefined
With an entirely unrelated section B, that is sibling to Section A Section B undefined
SubSection 1 Section B SubSection 1
And another subsection 1, but this time related to Section B. Section B SubSection 1

So we pass the collection of results as the source, and an augment function, that returns the heading 1 value - that is then kept until the next heading 1. (Similar for subSection using heading 2)

Parameters:
Name Type Description
source Array.<Object>

the collection of objects to check and augment.

augmentFn function

function accepting each entry, and returning the properties to "inherit"
or a property with a value of undefined - if it should not be preserved.

Returns:
  • new version of the source objects with the properties applied.
Type
Array.<Object>

(static) cleanProperties(objectsToBeCleaned) → {Array.<Object>}

Cleans all the properties of the array of objects in place (does not make Copies)

NOTE: This is faster than cleanProperties2, but the standard order of the properties (using Object.keys) will be altered.

Parameters:
Name Type Description
objectsToBeCleaned Array.<Object>
Returns:
  • cleaned objects
Type
Array.<Object>

(static) cleanProperties2(objectsToBeCleaned) → {CleanedProperties}

See:

Cleans properties on clones of objects.

Additionally, this returns a mapping of what the properties used to be named, as this can be helpful for rendering out tables.

Example
const badData = [
  { '"name"': 'john', num: '192', ' kind': ' s', '1st date': ' 2021-07-11T22:23:07+0100' },
  { '"name"': 'jane', num: '190', ' kind': ' c', '1st date': ' 2021-07-09T19:54:48+0100' },
  { '"name"': 'ringo', num: '190', ' kind': ' s', '1st date': ' 2021-07-08T17:00:32+0100' }
];
const cleaned = objectUtils.cleanProperties2(badData);
// {
//   labels: { 1st_date: '1st date', kind: 'kind', num: 'num' },
//   values: [
//     { name: 'john', num: '192', kind: ' s', '1st_date': ' 2021-07-11T22:23:07+0100' },
//     { name: 'jane', num: '190', kind: ' c', '1st_date': ' 2021-07-09T19:54:48+0100' },
//     { name: 'ringo', num: '190', kind: ' s', '1st_date': ' 2021-07-08T17:00:32+0100' }
//   ]
// }
Parameters:
Name Type Description
objectsToBeCleaned Array.<Object>

collection of objects to be cleaned

Returns:
  • { labels: Object - propertyName:originalProperty, values: cleaned collection }
Type
CleanedProperties

(static) cleanPropertyName(property) → {String}

Cleans an individual property

Parameters:
Name Type Description
property String
Returns:
Type
String

(static) cleanPropertyNames(objectKeys) → {Object}

Cleans the list of object keys - likely from a CSV

Parameters:
Name Type Description
objectKeys Object | Array.<String>
Returns:
  • object with key:value as original:new
Type
Object

(static) collapse(objectTree) → {Object}

See:

Collapse an object tree into a single object with all the properties.

Example
const targetObj = { make: 'Ford', model: 'F150', driver: {firstName:'John', lastName:'doe'}};
const collapsed - utils.collapse(targetObj);
console.log(`Hi ${collapsed.firstName}, how do you like your ${collapsed.model}?`);
// 'Hi John, how do you like your F150?
Parameters:
Name Type Description
objectTree Object
Returns:
  • object with all the properties added
Type
Object

(static) expand(targetObj) → {Object}

See:

The inverse of Flatten - this takes an object with dot notation properties, and creates the sub-objects as necessary to contain the properties defined.

Example:

flattenedObj = {
  first: 'john', last: 'doe',
  'friend.first': 'jane', 'friend.last': 'doe',
  'course.id': 'econ-101',
    'course.professor.id': 10101, 'course.professor.first': 'jim', 'course.professor.last': 'gifford'
};

expandedObj = utils.object.expand(flattenedObj);
// {
//  first: 'john', last: 'doe',
//  friend: { first: 'jane', last: 'doe' },
//  course: { id: 'econ-101', professor: { id: 10101, first: 'jim', last: 'gifford' }}
// };
Parameters:
Name Type Description
targetObj Object

a flattened object (with dot notation properties) to be expanded

Returns:
  • a new object with sub-objects for each of the dot-notation entries
Type
Object

(static) extractObjectProperties(objectList, propertyOrFnMap) → {Object}

See:

Similar to object.extractObjectProperty - this extracts out multiple property/vectors at a time.

Note that unlike numpy, there is a key preserved in the result - to better keep track of what the values were intended to represent.

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

utils.object.extractObjectProperties(weather, ['city', 'month']);
// { 
//   city: [ 'Seattle', 'New York', 'Chicago'],
//   month: ['Aug', 'Apr', 'Apr']
// }

Keys will be the the dot notation of the path used ex: prop[index].value or can be explicitly set through a [key, accessor] pair

utils.object.extractObjectProperties(weather, ['city', ['Month', 'month'], ['precipitation', r => r.precip]]);
// { 
//   city: [ 'Seattle', 'New York', 'Chicago'],
//   month: ['Aug', 'Apr', 'Apr'],
//   precipitation: [0.87, 3.94, 3.62]
// }

However, this can be helpful to extract values safely from deeply nested values

data = [{
   category_id: 'c884a636628bca341e', menu_item_id: 'mi88dc7bb31bc6104f1',
   item_sizes: [{ id: 'mio882f48820281cf4b6', price: 16.09 }]
},
{
   category_id: 'c884a636628bca341e', menu_item_id: 'mi8802b942e737df40d',
   item_sizes: [{ id: 'mio88b60bcd7dd202481', price: 17.09 }]
},
{
   category_id: 'c884a636628bca341e', menu_item_id: 'mi88ff22662b0c0644a',
   item_sizes: [{ id: 'mio88645e98cd8ffc42e', price: 14.99 }]
}];

utils.object.extractObjectProperty(data, ['menu_item_id', 'item_sizes[0].price']);
// {
//   menu_item_id: ['mi88dc7bb31bc6104f1', 'mi8802b942e737df40d', 'mi88ff22662b0c0644a'],
//   'item_sizes[0].price': [ 16.09, 17.09, 14.99 ]
// }

Note that this can also work with maps of properties / paths or functions

// note you can also pass maps with property name strings, or functions.
extractionMap = new Map();
extractionMap.set('city', null); // default the property by the key name
extractionMap.set('city2', 'city'); // specify the property to use
extractionMap.set('city3', (r) => r.city); // specify a function

utils.object.extractObjectProperties(weather, extractionMap);
// {
//   city: ['Seattle', 'New York', 'Chicago'],
//   city2: ['Seattle', 'New York', 'Chicago'],
//   city3: ['Seattle', 'New York', 'Chicago']
// };
Parameters:
Name Type Description
objectList Object | Array.<Object>

list of objects to extract the property from

propertyOrFnMap Map.<(function()|String)>

Name of the property or accessor function

Returns:
  • Object with the keys in the map as properties - extracting the values across all in list.
Type
Object

(static) extractObjectProperty(objectList, propertyOrFn) → {Array}

See:

Similar to a transpose, this finds all the values of a particular property within a list of objects.

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

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

However, this can be helpful to extract values safely from deeply nested values

data = [{
   category_id: 'c884a636628bca341e', menu_item_id: 'mi88dc7bb31bc6104f1',
   item_sizes: [{ id: 'mio882f48820281cf4b6', price: 16.09 }]
},
{
   category_id: 'c884a636628bca341e', menu_item_id: 'mi8802b942e737df40d',
   item_sizes: [{ id: 'mio88b60bcd7dd202481', price: 17.09 }]
},
{
   category_id: 'c884a636628bca341e', menu_item_id: 'mi88ff22662b0c0644a',
   item_sizes: [{ id: 'mio88645e98cd8ffc42e', price: 14.99 }]
}];

utils.object.extractObjectProperty(data, 'item_sizes[0].price');
// [ 16.09, 17.09, 14.99 ]
Parameters:
Name Type Description
objectList Object | Array.<Object>

list of objects to extract the property from

propertyOrFn function | String

Name of the property or accessor function

Returns:
  • single array the values stored in propertyOrFn across all objects in objectList.
Type
Array

(static) fetchObjectProperties(list, propertyNames, options) → {Array.<Object>}

See:

Fetches multiple properties from an object or list of objects.

testObj = {
 name: 'john',
 courses: [{ name: 'econ-101' }]
}
utils.object.fetchObjectProperty(testObj,
 { 'courseName': 'courses[0].?name', personName: 'name' });
// { courseName: 'econ-101', personName: 'john' }
Parameters:
Name Type Description
list Object | Array.<Object>

collection of objects to reduce

propertyNames Object.<String, any>

Object with the keys as as properties to return, and the values using dot notation to access related records and properties (ex: {parentName: 'somePropertyObject.parent.parent.name', childName: 'child.Name'})

options FetchObjectOptions

See FetchObjectOptions

Returns:
  • objects with the properties resolved (ex: {parentname, childName, etc.})
Type
Array.<Object>

(static) fetchObjectProperty(obj, propertyAccess, options) → {any}

See:

Accesses a property using a string

testObj = {
 name: 'john',
 courses: [{ name: 'econ-101' }]
}
utils.object.fetchObjectProperty(testObj, 'courses[0].?name');
// 'econ-101'

note that the options allow for safe property access

testObj = {
 name: 'john',
 courses: [{ name: 'econ-101' }]
}
utils.object.fetchObjectProperty(testObj, 'courses[0].courseId');
// throws an error

utils.object.fetchObjectProperty(testObj, 'courses[0].?courseId');
// null - because of optional condition operator

utils.object.fetchObjectProperty(testObj, 'courses[0].courseId', { safeAccess: true });
// null - because of the safe access option
Parameters:
Name Type Description
obj Object

object to access the properties on

propertyAccess String

dot notation for the property to access (ex: parent.obj.Name)

options FetchObjectOptions

See FetchObjectOptions

Returns:
  • the value accessed at the end ofthe property chain
Type
any

(static) filterObjectProperties(list, propertyNames) → {Array.<Object>}

Removes specific properties on an object or list of objects

Parameters:
Name Type Description
list Object | Array.<Object>

collection of objects to filter

propertyNames Array.<String>

list of the only properties to keep

Returns:
Type
Array.<Object>

(static) findWithProperties(objectsToCheck, …propertiesToFind) → {Array.<Object>}

See:
  • findWithoutProperties - if you want objects that do not have all properties

Finds objects that have any of the properties specified.

This can be very helpful when working with datasets that include mixed data (such as JSON)

const students = [
  { first: 'john', last: 'doe' }, { first: 'jane', last: 'doe' }, { first: 'jack', last: 'white', failure: 401 }
];

utils.findWithProperties(students, 'failure');
// { first: 'jack', last: 'white', failure: 401 }

Please note, that we can check a single object:

utils.findWithProperties({ first: 'john', last: 'doe' }, 'failure');
// []
Parameters:
Name Type Attributes Description
objectsToCheck Array.<Object>

the array of objects to check for the properties.

propertiesToFind String <repeatable>

the list of properties to find within the collection.

Returns:
  • Array of objects that have at least one of those properties
Type
Array.<Object>

(static) findWithoutProperties(objectsToCheck, …propertiesToFind) → {Array.<Object>}

See:
  • findWithProperties - if you want objects that do not have all properties

Finds objects that do not have ALL the properties specified.

This can be very helpful in ensuring all objects actually meet a specification and are not missing values.

const students = [
  { first: 'john', last: 'doe', age: 23 }, { first: 'jane', last: 'doe', age: 23 }, { first: 'jack', last: 'white', failure: 401 }
];

utils.findWithoutProperties(students, 'first', 'last', 'age');
// [{ first: 'jack', last: 'white', failure: 401 }]

utils.findWithoutProperties(students, 'failure');
// [{ first: 'john', last: 'doe', age: 23 }, { first: 'jane', last: 'doe', age: 23 }] 

Please note, that we can check a single object:

utils.findWithoutProperties(students[0], 'failure');
// []
Parameters:
Name Type Attributes Description
objectsToCheck Array.<Object>

the array of objects to check for the properties.

propertiesToFind String <repeatable>

the list of properties to find within the collection.

Returns:
  • Array of objects that are missing at least one of those properties
Type
Array.<Object>

(static) flatten(targetObj) → {Object}

See:

Flattens an object and sub-objects into dot notation - to have easier time understanding schemas and explainations.

example:

student = {
 first: 'john', last: 'doe',
 friend: { first: 'jane', last: 'doe' },
 course: { id: 'econ-101', professor: { id: 10101, first: 'jim', last: 'gifford' }}
};

flattenedObj = utils.object.flatten(student);
// {
//   first: 'john', last: 'doe',
//   'friend.first': 'jane', 'friend.last': 'doe',
//   'course.id': 'econ-101',
//     'course.professor.id': 10101, 'course.professor.first': 'jim', 'course.professor.last': 'gifford'
// };
Parameters:
Name Type Description
targetObj Object

Object with all properties and sub-objects to flatten.

Returns:
  • New object with dot notation properties
Type
Object

(static) flattenObjectOntoAnother(sourceObj, targetObjopt, prefixopt) → {Object}

While originally intended as a sub-implementation for Flatten, this was exposed in case additional cases ever arose.

Example:

student = { first: 'john', last: 'doe' };
friend = { first: 'jane', last: 'doe' };
course = { id: 'econ-101', professor: { id: 10101, first: 'jim', last: 'gifford' }};
flattenedObj = {};
flattenedObj = utils.object.flattenObjectOntoAnother(student, flattenedObj);
// { first: 'john', last: 'doe' }
flattenedObj = utils.object.flattenObjectOntoAnother(friend, flattenedObj, 'friend.');
// { first: 'john', last: 'doe', 'friend.first': 'jane', 'friend.last': 'doe' };
flattenedObj = utils.object.flattenObjectOntoAnother(course, flattenedObj, 'course.');
// { first: 'john', last: 'doe', 'friend.first': 'jane', 'friend.last': 'doe', 'course.id': 'econ-101',
//   'course.professor.id': 10101, 'course.professor.first': 'jim', 'course.professor.last': 'gifford' };

See flatten for a an alternative to achieve the same result.

Parameters:
Name Type Attributes Default Description
sourceObj Object

The object to review for source values / properties

targetObj Object <optional>
{}

The object to apply the dot notation properties onto

prefix String <optional>
''

the string prefix of any properties found on source, to apply onto target

Returns:
  • the targetObj with the properties applied (in place)
Type
Object

(static) formatProperties(collection, propertyTranslations) → {Array.<Object>}

See:

Translates specific properties to a new value on an object, or collection of objects.

The properties defined in the propertyTranslations argument is then the property to be updated. (All other properties remain the same)

You can either provide a function accepting the current value and returning the new value (any) => any

Or you can provide one of the common shorthands:

  • 'string'
  • 'float' or 'number'
  • 'int' or 'integer'
  • 'boolean'
data = [
  {station: 'A', isFahreinheit: 'true', offset: '0', temp: 98, type: 'F', descr: '0123'},
  {station: 'A', isFahreinheit: 'TRUE', offset: '2', temp: 99, type: 'F', descr: '0123456'},
  {station: 'A', isFahreinheit: 'false', offset: '3', temp: 100, type: 'F', descr: '0123456789'}
];

utils.object.format(data, ({
  //-- to a literal value
  type: 'C',
  //-- convert it to 'string', 'number' || 'float', 'int' || 'integer', 'boolean'
  offset: 'number',
  isFahreinheit: 'boolean',
  //-- or convert the value with a function accepting the current value
  //-- and returning the new value
  temp: (val) => (val - 32) * 0.5556
}));

// [
//   { station: 'A', isFahreinheit: true, offset: 0, temp: 36.669599999999996, type: 'C', descr: '0123' },
//   { station: 'A', isFahreinheit: true, offset: 2, temp: 37.2252, type: 'C', descr: '0123456' },
//   { station: 'A', isFahreinheit: false, offset: 3, temp: 37.7808, type: 'C', descr: '0123456789' }
// ];

Please note, you can pass a single object to be cleaned,
but it will be returned as an array of one object.

data = [{station: 'A', isFahreinheit: 'TRUE', offset: '2', temp: 99, type: 'F', descr: '0123456'}];

utils.object.format(data, ({
  //-- convert it to 'string', 'number' || 'float', 'int' || 'integer', 'boolean'
  offset: 'number',
  isFahreinheit: 'boolean'
}));

// [{station: 'A', isFahreinheit: true, offset: 2, temp: 99, type: 'F', descr: '0123456'}];
Parameters:
Name Type Description
collection Object

the list of objects to update specific properties

propertyTranslations Object

An object with property names as the properties to update
and the values as a function ((any) => any) accepting the current value, returning the new value.

Returns:
  • collection of objects transformed
Type
Array.<Object>

(static) generateSchema(targetObj) → {Object}

See:

Generates a JSON schema for an object

Parameters:
Name Type Description
targetObj any

object or array of objects

Returns:
  • JSON Schema
Type
Object

(static) getObjectPropertyTypes(list) → {Map.<String, Set.<String>>}

See:
  • generateSchema

returns a map of the types of fields stored

Parameters:
Name Type Description
list Object | Array.<Object>

collection of objects to check

Returns:
  • collection of the types and the fields of those types
Type
Map.<String, Set.<String>>

(static) isObject(testValue) → {Boolean}

Determines whether a value is an Object and not an Array or a Date

Parameters:
Name Type Description
testValue any

value to be tested

Returns:
  • whether the testValue is an Object and not an Array or a Date.
Type
Boolean

(static) join(objectArray, indexField, targetMap, joinFn) → {Array.<Object>}

Join values from an objectArray to a JavaScript Map.

For example:

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

cityLocations = new Map([
  ['Chicago', { locationId: 1, city: 'Chicago', lat: 41.8781, lon: 87.6298 }],
  ['New York', { locationId: 2, city: 'New York', lat: 40.7128, lon: 74.0060 }],
  ['Seattle', { locationId: 3, city: 'Seattle', lat: 47.6062, lon: 122.3321 }]
]);

utils.object.join(weather, 'city', cityLocations, (weather, city) => ({...weather, ...city}));
// [
//    {id:1, city:'Seattle',  month:'Aug', precip:0.87, locationId:3, lat:47.6062, lon:122.3321 },
//    null,
//    {id:3, city:'New York', month:'Apr', precip:3.94, locationId:2, lat:40.7128, lon:74.006 },
//    {id:6, city:'Chicago',  month:'Apr', precip:3.62, locationId:1, lat:41.8781, lon:87.6298 }
// ]

or join by lookup:

utils.object.join(weather, 'city', cityLocations, (weather, city) => ({...weather, city}));
[
  { id: 1, city: 'Seattle',  month: 'Aug', precip: 0.87, city:
    { city: 'Seattle', locationId: 3, lat: 47.6062, lon: 122.3321 }
  },
  null,
  { id: 3, city: 'New York', month: 'Apr', precip: 3.94, city:
    { city: 'New York', locationId: 2, lat: 40.7128, lon: 74.006 }
  },
  { id: 6, city: 'Chicago',  month: 'Apr', precip: 3.62, city:
    { city: 'Chicago', locationId: 1, lat: 41.8781, lon: 87.6298 }
  }
];

or performing a translation / calculate the index instead of a property:

const indexingFn = (weather) => `${weather.country}_${weather.city}`;
utils.object.join(weather, indexingFn, cityLocations, (weather, city) => ({...weather, ...city}));
// ...

The signature for the indexingFunction is (sourceObj:Object): {any} - providing the index to use against the map.

The signature for the mapping function is (sourceObj:Object, mappedObject:Object) => {Object}.

If the mappedObject could not be found by that index (left join), then mappedObject will be null.

As the results of the functions are mapped, you can either modify in-line (directly on the object), or on a clone of the object (ex: {...sourceObj})

Note, performing a JavaScript .map() call may be more performant in some cases, so consider it for more complex options.

Note: indexField can be either a string name of the field to join, or a function to be passed the object and generate the index

Parameters:
Name Type Description
objectArray Array.<Object>

collection of objects to join based on the target map

indexField function | String

property on each object in array to lookup against target map
Signature if a function: (sourceObj:Object): {any}

targetMap Map

Map with keys mapping to values to pass

joinFn function

function to call each time an objectArray object, has an indexField found in targetMap
Signature: (sourceObj:Object, mappedObject:Object) => {Object}

Returns:
  • Array of results returned from joinFn
Type
Array.<Object>

(static) joinProperties(objectArray, indexField, targetMap, …fields) → {Array.<Object>}

For cases where we simply want to pull values from one object to another.

For example:

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

cityLocations = new Map([
  ['Chicago', { locationId: 1, city: 'Chicago', lat: 41.8781, lon: 87.6298 }],
  ['New York', { locationId: 2, city: 'New York', lat: 40.7128, lon: 74.0060 }],
  ['Seattle', { locationId: 3, city: 'Seattle', lat: 47.6062, lon: 122.3321 }]
]);

utils.object.joinProperties(weather, 'city', cityLocations, 'lat', 'lon'));
// [
//    {id:1, city:'Seattle',  month:'Aug', precip:0.87, lat:47.6062, lon:122.3321 },
//    null,
//    {id:3, city:'New York', month:'Apr', precip:3.94, lat:40.7128, lon:74.006 },
//    {id:6, city:'Chicago',  month:'Apr', precip:3.62, lat:41.8781, lon:87.6298 }
// ]
Parameters:
Name Type Attributes Description
objectArray Array.<Object>

collection of objects to join based on the target map

indexField function | String

property on each object in array to lookup against target map
Signature if a function: (sourceObj:Object): {any}

targetMap Map.<any, Object>

Map with keys mapping to values to pass

fields String <repeatable>

List of fields to add to the objectArray in-place against values from targetMap

Returns:
  • The modified objectArray with the fields applied.
Type
Array.<Object>

(static) keys(objOrArray, maxRowsopt) → {Array.<String>}

See:

Safely gets the keys from an object or array of objects NOTE: much faster on object, as it will assume it needs to check all items in the array.

This can be quite helpful to understand a list of objects that are not uniform in properties.

Example
//-- finding all properties from a heterogeneous list
collection = [{ name: 'john', age: 23 }, { name: 'jane', age: 24, score: 4.0 }];
utils.object.keys(collection); // ['name', 'age', 'score']

//-- or using map on those keys
result = { name: 'john', age: 23, score: 4.0 };
utils.object.keys(result)
   .map(key => `${key}:${result[key]}`);  //-- you can now run map methods on those keys
Parameters:
Name Type Attributes Default Description
objOrArray Object | Array

a collection of objects (or a single object)

maxRows Number <optional>
-1

optional param - maximum number of rows to investigate for new keys if array passed. (ex: 2 means only investigate the first two rows)

Returns:
  • array of all the keys found
Type
Array.<String>

(static) mapByProperty(collection, propertyOrFn) → {Map.<String, Object>}

See:

Creates a map of a list of objects based on a specific property

Example
const data = [{ id: '123', name: 'jim' },
   { id: '456', name: 'mary' },
   { id: '789', name: 'sue' }];
mapByProperty(data, 'id');
// Map(
//      '123': { id: '123', name: 'jim' },
//      '456': { id: '456', name: 'mary' },
//      '789': { id: '789', name: 'sue' });
Parameters:
Name Type Description
collection Array.<Object>

collection of objects

propertyOrFn function | String

Name of the property or Function to return a value

Returns:
  • map using the propertyName as the key
Type
Map.<String, Object>

(static) mapProperties(objCollection, formattingFn, …propertiesToFormat)

Applies a function to a set of properties on an object, or collection.

This is shorthand for a mapping function, but useful if doing the same operation (like converting to compactNumbers, converting to string, etc)

For example, the two are equivalent:

const list = [
 { id: '100', age: '21', name: 'p1' },
 { id: '200', age: '22', name: 'p2' },
 { id: '300', age: '23', name: 'p3' },
 { id: '400', age: '24', name: 'p4' },
 { id: '500', age: '25', name: 'p5' }
];

const numToString = (val) => String(val);

const listMapProperties = utils.object.mapProperties(list, numToString, 'id', 'val');

const listMap = list.map((obj) => ({
 ...obj,
 id: numToString(obj.val),
 age: numToString(obj.val)
}));
Parameters:
Name Type Attributes Description
objCollection Array.<Object>

object or multiple objects that should have properties formatted

formattingFn function

function to apply to all the properties specified

propertiesToFormat any <repeatable>

list of properties to apply the formatting function

Returns:

{Object[] - clone of objCollection with properties mapped

(static) propertyFromList(objectArray, propertyOrFn) → {Array}

Maps an array of values to a single property.

For example:

const data = [{ record: 'jobA', val: 1 }, { record: 'jobA', val: 2 },
 { record: 'jobA', val: 3 }, { record: 'jobA', val: 4 },
 { record: 'jobA', val: 5 }, { record: 'jobA', val: 6 },
 { record: 'jobA', val: 7 }, { record: 'jobA', val: 8 },
 { record: 'jobA', val: 9 }, { record: 'jobA', val: 10 }
];

utils.object.propertyFromList(data, 'val')
//-- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

utils.object.propertyFromList(data, (r) => r.val);
//-- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
Parameters:
Name Type Description
objectArray Array.<Object>

Array of Objects to be mapped to a single property / value

propertyOrFn function | String

Name of the property or Function to return a value

Returns:
  • Array of values
Type
Array

(static) propertyInherit(source, …properties) → {Array.<Object>}

See:

Copies values from one record to the next or "inherits" the value previously used if the current value is undefined.

For example:

source = [
 { header: 'Section 1', text: 'A' },
 { header: undefined, text: 'B' },
 { header: undefined, text: 'C' },
 { header: 'Section 2', text: 'D' },
 { header: undefined, text: 'E' },
 { header: undefined, text: 'F' }
];
utils.object.propertyInherit(source, 'header');
// [
//  { header: 'Section 1', text: 'A' },
//  { header: 'Section 1', text: 'B' },
//  { header: 'Section 1', text: 'C' },
//  { header: 'Section 2', text: 'D' },
//  { header: 'Section 2', text: 'E' },
//  { header: 'Section 2', text: 'F' }
// ];
Parameters:
Name Type Attributes Description
source Array.<Object>

Collection of objects to inherit values

properties string <repeatable>

properties that should use the previous value if the current value is undefined

Returns:
  • collection of results
Type
Array.<Object>

(static) propertyValueSample(objCollection) → {Map.<String, any>}

Finds all the properties for objects in a collection, and provides the first 'non-empty' value found of each property.

Non-Empty means:

  • not null
  • not undefined
  • not an empty string
  • not an empty array

This can be especially helpful for heterogeneous collections and can be much faster than something like danfojs.describe

Example
let collection = [
 { first: 'jane', age: 23 },
 { first: 'john', last: 'doe', age: 21 }
];

utils.object.propertyValueSample(collection);
// { first: 'jane', last: 'doe', age: 23 }
Parameters:
Name Type Description
objCollection Array.<Object>

Array of objects that we want to understand

Returns:
  • Collection of all properties and the first 'non-empty' value found
Type
Map.<String, any>

(static) renameProperties(objects, propertyTranslations) → {Array.<Object>}

Property Reassign - either against a single object or an array of objects

Example
renameProperties(
 { '"first name"': 'john', '"last name"': 'doe' }, {'"first name"':'first_name'}
 ).deepEquals({first_name: 'john', '"last name"': 'doe'})
Parameters:
Name Type Description
objects Array.<Object>

objects to reassign - likely from a CSV

propertyTranslations Object

where property:value is original:new

Returns:
Type
Array.<Object>

(static) selectObjectProperties(list, propertyNames) → {Array.<Object>}

Keeps only specific properties on an object or list of objects

Parameters:
Name Type Description
list Object | Array.<Object>

collection of objects to filter

propertyNames Array.<String>

list of the only properties to keep

Returns:
Type
Array.<Object>

(static) setPropertyDefaults(targetObject, defaultObj)

See:
  • findWithoutProperties - to determine if any objects do not have a set of properties
  • keys - to get a list of unique properties of all objects in a list.

Sets values for objects that don't currently have the property

This is very helpful for ensuring that all objects have a property, or setting a value to make it easier to identify that it is 'N/A'

Note, that only the ownProperties on the default object are checked.

And values are applied to the target object, only if the property is not on the object (property is undefined)

Example
const students = [
  { first: 'john', last: 'doe', birthday: '2002-04-01' },
  { first: 'jane', last: 'doe', birthday: '2003-05-01' },
  { first: 'jack', last: 'white', failure: 401 }
];

utils.object.setPropertyDefaults(students, {
 first: '',
 last: '',
 birthday: ''
});

// [
//   { first: 'john', last: 'doe', birthday: '2002-04-01' },
//   { first: 'jane', last: 'doe', birthday: '2003-05-01' },
//   { first: 'jack', last: 'white', birthday: '', failure: 401 }
// ];
Parameters:
Name Type Description
targetObject Array.<Object> | Object

Object to apply the properties to
but ONLY if the object does not have that property (ex: undefined)

defaultObj Object

Object with the properties and defaults applied

Properties
Name Type Description
property any

the property to check, with the default value assigned

(static) union(source1, source2) → {Array.<Object>}

See:
  • join - to instead join based on a value instead of index
  • filterObjectProperties - to remove properties from collection of objects.

Unites the properties of two collections of objects.

For example:

source1 = [
 { first: 'john' },
 { first: 'jane' }
];
source2 = [
 { last: 'doe' },
 { last: 'dough' }
];
utils.object.union(source1, source2);
// [{ first: 'john', last: 'doe' },
//  { first: 'jane', last: 'dough' }];

Note that you can also pass a single object, to have it union to multiple.

source1 = [
 { first: 'john' },
 { first: 'jane' }
];
//-- same object to be applied to all
source2 = { last: 'doe' };

utils.object.union(source1, source2);
// [{ first: 'john', last: 'doe' },
//  { first: 'jane', last: 'doe' }];
Parameters:
Name Type Description
source1 Array.<Object> | Object

object or array of objects to union

source2 Array.<Object> | Object

object or array of objects to union

Returns:
  • collection of objects merging the values between the two sources
Type
Array.<Object>

(inner) setAddAll()

Adds all items into a set

Type Definitions

CleanedProperties

Properties:
Name Type Description
labels Object

an object with translations of the fields and labels

Properties
Name Type Description
property String

for each translated property, stores the original property name

values Array.<Object>

cleaned values

Labels and Values from object.cleanProperties2

{
  labels: { date: 'date', kind: 'kind', num: 'num' },
  values: [
    { date: ' 2021-07-11T22:23:07+0100', kind: ' s', num: '192' },
    { date: ' 2021-07-09T19:54:48+0100', kind: ' c', num: '190' },
    { date: ' 2021-07-08T17:00:32+0100', kind: ' s', num: '190' }
  ]
};
Type:
  • Object

FetchObjectOptions

Properties:
Name Type Description
safeAccess Boolean

whether to safely access, even if the path cannot be found

Options for fetching object properties

Type:
  • Object