Utility for working with and massaging javascript objects.
- Describe objects
- isObject() - Determine if a given value is an Object and not a Number, String, Array or Date
- keys() - Safely get the keys of an object or list of objects
- getObjectPropertyTypes() - describe the properties of a list of objects
- generateSchema() - generate a schema / describe properties of a list of objects
- findWithoutProperties() - find objects without ALL the properties specified
- findWithProperties() - find objects with any of the properties specified
- propertyValueSample(collection) - finds non-empty values for all properties found in the collection
- Fetch child properties from related objects
- fetchObjectProperty(object, string) - use dot notation to bring a child property onto a parent
- fetchObjectProperties(object, string[]) - use dot notation to bring multiple child properties onto a parent
- join(array, index, map, fn) - join a collection against a map by a given index
- join(array, index, map, ...fields) - join a collection, and copy properties over from the mapped object.
- Fetch values safely
- propertyFromList(array, propertyName) - fetches a specific property from all objects in a list
- extractObjectProperty(list, propertyNameOrFn) - extracts a property or fn across all objects in list.
- extractObjectProperties(list, propertyNameOrFnMap) - extracts multiple propertie or fn across all objects in list.
- Apply deep values safely
- objAssign(object, property, value) - Applies properties to an object in functional programming style.
- augment(object, augmentFn) - Applies properties to an object similar to Map
- objAssignEntities(object, [property, value]) - Applies properties to an object using Array values - [key,value]
- setPropertyDefaults() - sets values for objects that don't currently have the property
- object.applyPropertyValue - safely apply a value deeply and safely
- object.applyPropertyValues - apply an array of values safely and deeply against a list of objects.
- Manipulating objects
- augmentInherit(object, augmentFn) - Applies properties to a collection of objects, 'remembering' the last value - useful for 1d to *D lists.
- object.propertyInherit(object, ...propertyName) - Copies values from one record to the next if the current value is undefined.
- selectObjectProperties() - keep only specific properties
- filterObjectProperties() - remove specific properties
- mapProperties(collection, fn, ...properties) - map multiple properties at once (like parseInt, or toString)
- formatProperties(collection, propertyTranslation) - map specific properties (ex: toString, toNumber, etc)
- union(objectList1, objectList2) - Unites the properties of two collections of objects.
- Rename properties
- cleanProperties() - correct inaccessible property names in a list of objects - in place
- cleanProperties2() - correct inaccessible property names in a list of objects - on a cloned list
- cleanPropertyNames() - create a translation of inaccessible names to accessible ones
- cleanPropertyName() - create a translation of a specific property name to be accessible.
- renameProperties() - Use a translation from old property names to new ones
- Flatten object properties
- collapse() - coalesce properties from all nested objects to the base object.
- flatten() - creates dot notation properties (similar to arrow notation) of all child objects.
- expand() - expands dot notation properties onto sub children (inverse of flatten)
- Create Map of objects by key
- Convert collections of objects
- objectCollectionFromArray - convert rows/columns 2d array to objects
- module:object.objectCollectionToArray - convert objects to a rows/columns 2d array
- module:object.objectCollectionFromDataFrameObject - convert tensor object with each field as 1d array of values
- module:object.objectCollectionToDataFrameObject - convert objects from a tensor object
Members
(static) MAX_COLLAPSE_DEPTH :Number
- See:
-
- collapse() - used with collapse
The maximum depth that a collapse will go to
Type:
- Number
Methods
(static) applyPropertyValue(obj, path, value) → {Object}
- See:
-
- object.applyPropertyValues - to safely and deeply apply the list of values extracted to a list of objects.
- object.extractObjectProperty - to safely extract a deep value
- object.fetchObjectProperty - to extract a deep value and optionally throw if not found
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:
-
- module:object.applyPropertyValue - to apply a single value to a single object
- module:object.fetchObjectProperties - to fetch multiple properties at once into objects
- object.extractObjectProperties - to extract properties into array vectors instead of objects
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 |
||
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:
-
- object.propertyInherit - if you want to use values already on the object
- augment() - Applies properties to an object similar to Map
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" |
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}
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}
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:
-
- flatten() - as the inverse
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:
-
- extractObjectProperty(list, propertyNameOrFn) to see all the values stored for a single property.
- object.applyPropertyValues - to safely and deeply apply the list of values extracted to a list of objects.
- module:object.fetchObjectProperties - to fetch multiple properties at once into objects
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:
-
- unique() to see all the unique values stored
- object.extractObjectProperties - to extract into array vectors
- object.fetchObjectProperty - to extract a deep value and optionally throw if not found
- object.applyPropertyValue - to apply a single value to a single object using dot notation safely
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:
-
- object.fetchObjectProperty - to safely fetch a single value
- object.applyPropertyValues - to safely and deeply apply the list of values extracted to a list of objects.
- object.extractObjectProperties - to extract into array vectors instead of objects
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 |
Returns:
- objects with the properties resolved (ex: {parentname, childName, etc.})
- Type
- Array.<Object>
(static) fetchObjectProperty(obj, propertyAccess, options) → {any}
- See:
-
- module:object.fetchObjectProperties - to fetch multiple properties at once into objects
- object.extractObjectProperty - to safely extract a deep value without options
- object.applyPropertyValue - to apply a single value to a single object using dot notation safely
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: |
options |
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:
-
- expand() - as the inverse
- describeObjects(collection, options) - as a way to describe the values provided
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:
-
- augment(collection, fn) - to add in new properties
- TableGenerator#formatter - for other examples
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 |
Returns:
- collection of objects transformed
- Type
- Array.<Object>
(static) generateSchema(targetObj) → {Object}
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 |
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 |
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 |
|
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>}
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:
-
- group(collection, propertyOrFn) - if there is a possibility the records are not unique
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) → {Array.<Object>}
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:
- clone of objCollection with properties mapped
- Type
- Array.<Object>
(static) objectCollectionFromArray(arrayCollection, headersopt) → {Array.<Object>}
- See:
Converts a 2d array to a collection of objects.
For Example:
weather = [
[ 'id', 'city', 'month', 'precip' ],
[ 1, 'Seattle', 'Aug', 0.87 ],
[ 0, 'Seattle', 'Apr', 2.68 ],
[ 2, 'Seattle', 'Dec', 5.31 ]
]
utils.object.objectCollectionFromArray(weather);
// [
// { id: 1, city: 'Seattle', month: 'Aug', precip: 0.87 },
// { id: 0, city: 'Seattle', month: 'Apr', precip: 2.68 },
// { id: 2, city: 'Seattle', month: 'Dec', precip: 5.31 }
// ];
Note that the headers can be optionally provided separately.
weather = [
[ 1, 'Seattle', 'Aug', 0.87 ],
[ 0, 'Seattle', 'Apr', 2.68 ],
[ 2, 'Seattle', 'Dec', 5.31 ]
];
headers = [ 'id', 'city', 'month', 'precip' ];
utils.object.objectCollectionFromArray(weather, headers);
// [
// { id: 1, city: 'Seattle', month: 'Aug', precip: 0.87 },
// { id: 0, city: 'Seattle', month: 'Apr', precip: 2.68 },
// { id: 2, city: 'Seattle', month: 'Dec', precip: 5.31 }
// ];
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
arrayCollection |
Array.<Array> | 2d collection of values |
|
headers |
Array.<String> |
<optional> |
Optional set of headers to use if not present in first row 0 |
Returns:
- list of objects
- Type
- Array.<Object>
(static) objectCollectionFromDataFrameObject(dataFrameObject) → {Array.<Object>}
- See:
Convert a DataFrame Object into a collection of objects.
This uses properties with 1d tensor lists and converts them to a list of objects.
const weather = {
id: [1, 0, 2],
city: ['Seattle', 'Seattle', 'Seattle'],
month: ['Aug', 'Apr', 'Dec'],
precip: [0.87, 2.68, 5.31]
};
ObjectUtils.objectCollectionFromDataFrameObject(weather);
// [
// { id: 1, city: 'Seattle', month: 'Aug', precip: 0.87 },
// { id: 0, city: 'Seattle', month: 'Apr', precip: 2.68 },
// { id: 2, city: 'Seattle', month: 'Dec', precip: 5.31 }
// ];
Parameters:
Name | Type | Description |
---|---|---|
dataFrameObject |
Object | Object with properties holding 1d tensor arrays |
Returns:
- collection of objects
- Type
- Array.<Object>
(static) objectCollectionToArray(arrayCollection, headersnullable) → {Array.<Object>}
- See:
Converts a 2d array to a collection of objects.
For Example:
weather = [
{ id: 1, city: 'Seattle', month: 'Aug', precip: 0.87 },
{ id: 0, city: 'Seattle', month: 'Apr', precip: 2.68 },
{ id: 2, city: 'Seattle', month: 'Dec', precip: 5.31 }
];
utils.object.objectCollectionToArray(weather);
// [
// [ 'id', 'city', 'month', 'precip' ],
// [ 1, 'Seattle', 'Aug', 0.87 ],
// [ 0, 'Seattle', 'Apr', 2.68 ],
// [ 2, 'Seattle', 'Dec', 5.31 ]
// ]
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
arrayCollection |
Array.<Array> | 2d collection of values |
|
headers |
Array.<String> |
<nullable> |
Optional set of headers to use if not present in first row 0 |
Returns:
- list of objects
- Type
- Array.<Object>
(static) objectCollectionToDataFrameObject(dataFrameObject) → {Array.<Object>}
- See:
Convert a DataFrame Object into a collection of objects.
This uses properties with 1d tensor lists and converts them to a list of objects.
const weather = [
{ id: 1, city: 'Seattle', month: 'Aug', precip: 0.87 },
{ id: 0, city: 'Seattle', month: 'Apr', precip: 2.68 },
{ id: 2, city: 'Seattle', month: 'Dec', precip: 5.31 }
];
ObjectUtils.objectCollectionToDataFrameObject(weather);
// {
// id: [1, 0, 2],
// city: ['Seattle', 'Seattle', 'Seattle'],
// month: ['Aug', 'Apr', 'Dec'],
// precip: [0.87, 2.68, 5.31]
// };
Parameters:
Name | Type | Description |
---|---|---|
dataFrameObject |
Object | Object with properties holding 1d tensor arrays |
Returns:
- collection of objects
- Type
- Array.<Object>
(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:
-
- object.augmentInherit - to create new properties to inherit
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 |
||||||
defaultObj |
Object | Object with the properties and defaults applied Properties
|
(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
|
||||||
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