npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

object-hierarchy-access

v0.33.0

Published

Get/Set value from/to JS object hierarchy properties

Downloads

134

Readme

Importing methods

For ES module environment, use import to import methods:

import { get, set } from 'object-hierarchy-access';

For commonjs environment, use requre to import methods:

const { get, set } = require('object-hierarchy-access')

For AMD module environment, define module object-hierarchy-access from file dist/index.

For global mode, methods are under global variable ObjectHierarchyAccess.

Assigning

Setting a value

All methods for setting a value below have same parameters definition:

setValue(targetObject, ...hierarchyProperties, lastProperty, value);
setValue(targetObject, [...hierarchyProperties, lastProperty], value);

set

Set value to object's hierarchy properties, returns the object:

import { set } from 'object-hierarchy-access';
const obj = {};
set(obj, 'a', 'b', 'c', 100);
console.log(obj.a.b.c); // 100

Properties could be in arrays:

import { set } from 'object-hierarchy-access';

const obj = {};
set(obj, ['a', 'b', 'c'], 100);
console.log(obj.a.b.c); // 100

set(obj, ['d', 'e', 'f'], ['g', 'h', 'i'], 200);
console.log(obj.d.e.f.g.h.i); // 200

Create root object at the same time:

import { set } from 'object-hierarchy-access';
const obj = set({}, 'a', 'b', 'c', 100);
console.log(obj.a.b.c); // 100

setIfUndef

Only set value if last hierarchy property not exists or its value is undefined:

import { setIfUndef } from 'object-hierarchy-access';
const obj = {};
setIfUndef(obj, 'a', 'b', 'collection', []);
obj.a.b.collection.push(100);
console.log(obj.a.b.collection); // [100]

setIfUndef(obj, 'a', 'b', 'collection', []); // will not override previous array
obj.a.b.collection.push(200);
console.log(obj.a.b.collection); // [100, 200]

It is also possible to create the object at the same time:

import { setIfUndef } from 'object-hierarchy-access';
const obj = setIfUndef({}, 'a', 'b', 'c', 100);
console.log(obj.a.b.c); // 100

Customize hierarchy object creating

Property can ba a descriptor object rather than a primitive value for non-last property item. The descriptor shape is {name|getName, value|type|create, override?, created?, skipped?, got?}.

  • name is a primitive property name
  • getName(parent) is a callback function to get property name
  • value should be an object assign to parent object's name
  • type is a constructor function(or class) with no parameter that can be used to create object, assign to parent object's name
  • create(parent, name) is a callback function that returns a customized object assign to parent object's name
  • override determines if always create new hierarchy object even property already exists
  • created(parent, name, current) is a callback function when new hierarchy object has been created
  • skipped(parent, name, current) is a callback function when hierarchy object already exists and skipped
  • got(parent, name, current) is a callback function when current hierarchy object got no matter it is created or skipped.

Property can also be a function, it just act as getName callback in object descriptor.

If no name related option specified, property name will be undefined.

If no value related option specified, value will be {}.

const obj = set({}, 'a', {name: 'b', value: []}, '0', 100);
console.log(obj); // {a: {b: [100]}}

const obj2 = set({}, 'a', {name: 'b', value: {}}, 'c', 100);
console.log(obj2); // {a: {b: {c: 100}}
const obj = set({}, 'a', {name: 'b', type: Array}, '0', 100);
console.log(obj); // {a: {b: [100]}}
const obj = set({}, 'a', {name: 'b', create: () => [1, 2, 3]}, '3', 200);
console.log(obj); //  {a: {b: [1, 2, 3, 200]}}
const obj = set({}, 'a', 'b', 'c', 100);
setIfUndef(obj, 'a', 'b', 'c', 200);
console.log(obj.a.b.c); // 100

setIfUndef(obj, 'a', {name: 'b', override: true}, 'c', 300);
console.log(obj.a.b.c); // 300

assign and assignIfUndef

Just like set and setIfUndef, but returns the second last hierarchy object which contains the last hierarchy property. Cannot create root object at the same time since the whole object is not returned.

import { assign } from 'object-hierarchy-access';
const obj = {};
const result = assign(obj, 'a', 'b', 'c', 100);
console.log(obj.a.b.c); // 100
console.log(result); // {c: 100}
console.log(result === obj.a.b); // true

put and putIfUndef

Just like set and setIfUndef, but returns the last hierarchy value. Cannot create root object at the same time since the whole object is not returned.

import { putIfUndef } from 'object-hierarchy-access';
const obj = {};
const collection = putIfUndef(obj, 'a', 'b', 'collection', []);
collection.push(100);

const anotherCollection = putIfUndef(obj, 'a', 'b', 'collection', []);
anotherCollection.push(200);
console.log(anotherCollection); // [100, 200];
console.log(collection === anotherCollection); // true
console.log(collection === obj.a.b.collection); // true

Creating hierarchy properties only

All methods for creating hierarchy properties structure below have same parameters definition:

createHierarchyProperty(targetObject, ...hierarchyProperties);
createHierarchyProperty(targetObject, [hierarchyProperties]);

setProp

Use primitive value as property name or property descriptor object to create hierarchy property. Can create root object at the same time. Returns the object.

import { setProp } from 'object-hierarchy-access';
const obj1 = {};
setProp(obj1, 'a', 'b', 'c');
console.log(obj1); // {a:{b:{c:{}}}}

const obj2 = setProp({}, 'a', 'b', {name:'c', type:Array});
console.log(obj2); // {a:{b:{c:[]}}}

setPropIfUndef

Only create last hierarchy property if not exists or its value is undefined.

import { setPropIfUndef } from 'object-hierarchy-access';
const obj = {};
setPropIfUndef(obj, 'a', 'b', {name:'c', value:[100]});
console.log(obj); // {a:{b:{c:[100]}}}

setPropIfUndef(obj, 'a', 'b', {name:'c', value:{}}); // will not override previous array
console.log(obj); // {a:{b:{c:[100]}}}

assignProp and assignPropIfUndef

Just like setProp and setPropIfUndef, but returns the second last hierarchy. Cannot create root object at the same time.

import { assignProp } from 'object-hierarchy-access';
const obj = {};
const result = assignProp(obj, 'a', 'b', 'c');
console.log(obj); // {a:{b:{c:{}}}}
console.log(result); // {c:{}}

putProp and putPropIfUndef

Just like setProp and setPropIfUndef, but returns the last hierarchy. Cannot create root object at the same time.

import { putProp } from 'object-hierarchy-access';
const obj = {};
const result = putProp(obj, 'a', 'b', 'c');
console.log(obj); // {a:{b:{c:{}}}}
console.log(result); // {}
console.log(result === obj.a.b.c); // true

Setting value VS Creating hierarchy property

Sometimes setting value methods and creating hierarchy property methods can be replaced with each other. The following two blocks of codes have the same effect:

import { set } from 'object-hierarchy-access';
set({}, 'a', 'b', 'c', []);
import { setProp } from 'object-hierarchy-access';
setProp({}, 'a', 'b', {name:'c', value:[]});

The first example is shorter, while the second one is useful if you want to combine property name with its value as a descriptor.

For -IfUndef methods, if last hierarchy property value is very expensive for creating, use creating hierarchy methods with descriptor's property type or create, could avoid creating unnecessary values except the first time.

import { setIfUndef } from 'object-hierarchy-access';
const obj = {};
setIfUndef(obj, 'a', 'b', 'c', []);
setIfUndef(obj, 'a', 'b', 'c', []);  // the array instance is created and then abandoned
import { setPropIfUndef } from 'object-hierarchy-access';
const obj = {};
setPropIfUndef(obj, 'a', 'b', {name:'c', type:Array});  // the array instance is created
setPropIfUndef(obj, 'a', 'b', {name:'c', type:Array});  // will not create array instance
setPropIfUndef(obj, 'a', 'b', {name:'c', create: ()=>[]});  // will not create array instance

For setting value methods, hierarchy properties only created if not exists by default, unless override is specified. Value will always be overridden unless using -IfUndef related methods.

For creating hierarchy property methods, non-last hierarchy properties only created if not exists by default, unless override is specified. For last hierarchy property, non -IfUndef methods overrides existing property and ignore override, while -IfUndef methods will not unless override is true.

const obj = {};
setPropIfUndef(obj,'a','b',{name:'c', value:[]}); // obj.a.b.c === []
setPropIfUndef(obj,'a','b',{name:'c', value:{}}); // obj.a.b.c not changed
setPropIfUndef(obj,'a','b',{name:'c', value:{}, override:true}); // obj.a.b.c === {} 

Summary: names for assigning methods

Returns\Category|Setting Value|Creating Hierarchy Property ----------------|-------------|------------------ Root Object|set, setIfUndef|setProp, setPropIfUndef Second Last Hierarchy|assign, assignIfUndef|assignProp, assignPropIfUndef Last Hierarchy|put, putIfUndef|putProp, putPropIfUndef

Getting

get

Get value from object's hierarchy properties.

Parameter definition:

get(targetObject, ...hierarchyProperties);
get(targetObject, [hierarchyProperties]);

Primitive name property

Specifying properties by string, number or symbol:

import { get } from 'object-hierarchy-access';
const obj = {a: {b: {c: 100}}};
get(obj, 'a', 'b'); // returns {c: 100}
get(obj, 'a', 'b', 'c'); // returns 100
get(obj, ['a', 'b', 'c']); // returns 100

Object property

Property can be a descriptor object, which its shape is {name|getName|getValue, got?}.

  • name is a primitive property name
  • getName(parent) is a callback function to get property name
  • getValue(parent) is a callback function to get property value directly
  • got(parent, name, current) is a callback when value has been got from parent's name property, name will be 'undefined' if value is got by getValue
import { get } from 'object-hierarchy-access';
const obj = {a: {b: {c: 100}}};
get(obj,
	{
		name: 'a',
		got: (parent, name, current) => {
			/*
			parent => {a: {b: {c: 100}}};
			name => 'a';
			current => {b: {c: 100}};
			*/
		}
	},
	{
		getName: () => 'b',
		got: (parent, name, current) => {
			/*
			parent => {b: {c: 100}};
			name => 'b';
			current => {c: 100};
			*/
		}
	},
	{
		getValue: parent => parent.c,
		got: (parent, name, current) => {
			/*
			parent => {c: 100};
			name => 'undefined';
			current => 100;
			*/
		}
	}
);

Function property

Property can also be a function, it just acts as getValue callback in object descriptor.

const obj = {a: {value: 1, b1: {c: 100}, b2: {c: 200}}};
get(obj, 'a', parent => parent.value === 1 ? parent.b1 : parent.b2, 'c'); // returns 100

exist

Check if hierarchical property name exists on target object, not care if last hierarchy property value is undefined or null.

Parameter definition:

exist(target, ...propertyNames);
exist(target, [propertyNames]);
import { exist } from 'object-hierarchy-access';
const obj = {a: {b: {c: 0}}};
exist(obj, 'a', 'b', 'c');  // true
exist(obj, 'a', 'b', 'd');  // false

array2map

Turns array of object into a hash map entries.

Parameter definition:

array2map(sourceArray, keyHierarchyProperty|[keyHierarchyProperties], valueHierarchyProperty|[valueHierarchyProperties]);

"hierarchyProperty" is same as get's, can be a property name, a descriptor, or a function act as getValue. It is used for each item in array.

import { array2map } from 'object-hierarchy-access';

const products = [
	{
		productId: 'p1',
		price: 100
	},
	{
		productId: 'p2',
		price: 200
	}
];

const productPrices = array2map(products, 'productId', 'price');
/*
{
	p1: 100,
	p2: 200
}
*/
import { array2map } from 'object-hierarchy-access';

const products = [
	{
		product: {id: 'p1'},
		price: {value: 100}
	},
	{
		product: {id: 'p2'},
		price: {value: 200}
	}
];

const productPrices = array2map(products, ['product', 'id'], ['price', 'value']);
/*
{
	p1: 100,
	p2: 200
}
*/

map2array

Turns hash map entries object into array.

Parameter definition:

map2array(sourceEntry, keyPropName|getKeyPropName, valuePropName|getValuePropName);
  • keyPropName will becomes result item's property name to hold key
  • getKeyPropName(source, hashKey, hashValue) can customize keyName for each entry
  • valuePropName will becomes result item's property name to hold value
  • getValuePropName(source, hashKey, hashValue) can customize valueName for each entry
import { map2array } from 'object-hierarchy-access';

const productPrices = {
	p1: 100,
	p2: 200
};

const products = map2array(productPrices, 'productId', 'price');
/*
[
	{
		productId: 'p1',
		price: 100
	},
	{
		productId: 'p2',
		price: 200
	}
]
*/

To customize getting value from more complex structure, consider using pick.

traverse

Go through each hierarchy with a callback (parent, name, current) => false?. Valid hierarchy property format is same as get. Returns false in callback to terminate hierarchy iteration.

Parameter definition:

traverse(targetObject, ...hierarchyProperties, callback);
traverse(targetObject, [hierarchyProperties], callback);
import { traverse } from 'object-hierarchy-access';
const node1 = {}, node2 = {}, node3 = {};
node1.next = node2;
node2.next = node3;
node3.next = null;
const linkedList = { next: node1 };

let nextId = 1;
traverse(linkedList, 'next', 'next', 'next', (parent, name, current) => { current.id = nextId++; });
console.log(node1.id, node2.id, node3.id); // 1, 2, 3

traverseReverse

Just like traverse, but callback was invoked from last hierarchy to first hierarchy. Returns false in callback to terminate hierarchy iteration.

import { traverseReverse } from 'object-hierarchy-access';
const task = {
	done: false,
	subTasks: [
		{
			done: false,
			subTasks: [
				{done: false},  // will be done
				{done: true}
			]
		}
	]
};

task.subTasks[0].subTasks[0].done = true;
traverseReverse(task, 'subTasks', 0, 'subTasks', (parent, name, current) => {
	if (Array.isArray(current)) {
		parent.done = current.every(task => task.done);
	}
});
console.log(task.done); // true
console.log(task.subTasks[0].done); // true

select

Choose hierarchy properties from object, and got a new object only contains chosen properties.

Parameter definition:

select(targetObject, ...selectedHierarchyProperties);

Each selected hierarchy property parameter can be an array of properties, a single primitive property, a descriptor object {names|getNames, got?, mapName?, mapValue?, mapped?} or a callback function as descriptor object's getNames.

  • names is an array of primitive properties, or a single primitive property
  • getNames(current) is a callback function to get property names, should returns array of properties or a single property.
  • got(parent, name, current) is a callback function when current hierarchy property value is got.
  • mapName(parent, name, current) is a callback function if you want to rename hierarchy property, make sure mapped names are not conflict under same hierarchy.
  • mapValue(parent, name, current) is a callback function if you want to transform property value into another shape. Deeper hierarchy selection will based on mapped value.
  • mapped(parent, mappedName, mappedCurrent) is a callback function when mapping is done.

To select all properties of an object, specify undefined as names, no matter this object is an array or regular object.

import { select } from 'object-hierarchy-access';
const rooms = {
	building1: {
		floor1: [{roomNo: '1-101'}, {roomNo: '1-102'}, {roomNo: '1-103'}],
		floor2: [{roomNo: '1-201'}, {roomNo: '1-202'}, {roomNo: '1-203'}],
		floor3: [{roomNo: '1-301'}, {roomNo: '1-302'}, {roomNo: '1-303'}]
	},
	building2: {
		floor1: [{roomNo: '2-101'}, {roomNo: '2-102'}, {roomNo: '2-103'}],
		floor2: [{roomNo: '2-201'}, {roomNo: '2-202'}, {roomNo: '2-203'}],
		floor3: [{roomNo: '2-301'}, {roomNo: '2-302'}, {roomNo: '2-303'}]
	},
	building3: {
		floor1: [{roomNo: '3-101'}, {roomNo: '3-102'}, {roomNo: '3-103'}],
		floor2: [{roomNo: '3-201'}, {roomNo: '3-202'}, {roomNo: '3-203'}],
		floor3: [{roomNo: '3-301'}, {roomNo: '3-302'}, {roomNo: '3-303'}]
	},
	building4: {}
};

const allFloor1Rooms = select(rooms, ['building1', 'building2', 'building3', 'building4'], 'floor1');
/*
{
	building1: {
		floor1: [{roomNo: '1-101'}, {roomNo: '1-102'}, {roomNo: '1-103'}]
	},
	building2: {
		floor1: [{roomNo: '2-101'}, {roomNo: '2-102'}, {roomNo: '2-103'}]
	},
	building3: {
		floor1: [{roomNo: '3-101'}, {roomNo: '3-102'}, {roomNo: '3-103'}]
	},
	building4: {}
}
*/

pick

Similar to select, but only picks last hierarchy values into the same array and return. Hierarchy selection option mapName is useless in this case.

import { pick } from 'object-hierarchy-access';
const rooms = {
	building1: {
		floor1: [{roomNo: '1-101'}, {roomNo: '1-102'}, {roomNo: '1-103'}],
		floor2: [{roomNo: '1-201'}, {roomNo: '1-202'}, {roomNo: '1-203'}],
		floor3: [{roomNo: '1-301'}, {roomNo: '1-302'}, {roomNo: '1-303'}]
	},
	building2: {
		floor1: [{roomNo: '2-101'}, {roomNo: '2-102'}, {roomNo: '2-103'}],
		floor2: [{roomNo: '2-201'}, {roomNo: '2-202'}, {roomNo: '2-203'}],
		floor3: [{roomNo: '2-301'}, {roomNo: '2-302'}, {roomNo: '2-303'}]
	},
	building3: {
		floor1: [{roomNo: '3-101'}, {roomNo: '3-102'}, {roomNo: '3-103'}],
		floor2: [{roomNo: '3-201'}, {roomNo: '3-202'}, {roomNo: '3-203'}],
		floor3: [{roomNo: '3-301'}, {roomNo: '3-302'}, {roomNo: '3-303'}]
	},
	building4: {}
};
const allFloor1Rooms = pick(rooms, ['building1', 'building2', 'building3', 'building4'], 'floor1', undefined);
/*
[
	{roomNo: '1-101'}, {roomNo: '1-102'}, {roomNo: '1-103'},
	{roomNo: '2-101'}, {roomNo: '2-102'}, {roomNo: '2-103'},
	{roomNo: '3-101'}, {roomNo: '3-102'}, {roomNo: '3-103'},
	{roomNo: 'x-101'}, {roomNo: 'x-102'}, {roomNo: 'x-103'}
]
*/
import { pick } from 'object-hierarchy-access';
const productPrices = {
	p1: {price: 100},
	p2: {price: 200}
};
const products = pick(productPrices, {
	names: undefined,
	mapValue: (parent, name, current) => ({
		productId: name,
		price: current.price
	})
});
/*
[
	{
		productId: 'p1',
		price: 100
	},
	{
		productId: 'p2',
		price: 200
	}
]
*/

group

Divide first hierarchy properties into different hierarchical groups.

If original object is an Array, the grouped data are also arrays.

Parameter definition:

group(targetObject, ...groupParams);
group(targetObject, [groupParams]);

groupParam can be an descriptor object which its shape is {type?|create?, by}, or a callback function as descriptor object's by.

  • type is the group container object type, defaults to Object
  • create(parent) is a callback function to create group container object
  • by(parent, name, current) is a callback for iterating each property on first hierarchy, should returns a group name

parent is targetObject. name is a property name of first hierarchy. current is parent[name].

Specify multiple groupParams will create multiple group hierarchies.

import { group } from 'object-hierarchy-access';
const rooms = {
	building1: {
		floor0: [{roomNo: '1-001'}, {roomNo: '1-002'}, {roomNo: '1-003'}],
		floor1: [{roomNo: '1-101'}, {roomNo: '1-102'}, {roomNo: '1-103'}],
		floor2: [{roomNo: '1-201'}, {roomNo: '1-202'}, {roomNo: '1-203'}],
		floor3: [{roomNo: '1-301'}, {roomNo: '1-302'}, {roomNo: '1-303'}]
	},
	building2: {
		floor1: [{roomNo: '2-101'}, {roomNo: '2-102'}, {roomNo: '2-103'}],
		floor2: [{roomNo: '2-201'}, {roomNo: '2-202'}, {roomNo: '2-203'}],
		floor3: [{roomNo: '2-301'}, {roomNo: '2-302'}, {roomNo: '2-303'}]
	},
	building3: {
		floor1: [{roomNo: '3-101'}, {roomNo: '3-102'}, {roomNo: '3-103'}],
		floor2: [{roomNo: '3-201'}, {roomNo: '3-202'}, {roomNo: '3-203'}],
		floor3: [{roomNo: '3-301'}, {roomNo: '3-302'}, {roomNo: '3-303'}],
		floor4: [{roomNo: '3-401'}, {roomNo: '3-402'}, {roomNo: '3-403'}]
	},
	building4: {}
};

const groupByHasFloor0ByOddEven = group(
	rooms,
	(parent, name, current) => current.floor0 ? 'hasFloor0' : 'hasNoFloor0',
	(parent, name, current) => Object.keys(current).length % 2 ? 'oddFloors' : 'evenFloors'
);
/*
{
	hasFloor0: {
		evenFloors: {
			building1: {
				floor0: [{roomNo: '1-001'}, {roomNo: '1-002'}, {roomNo: '1-003'}],
				floor1: [{roomNo: '1-101'}, {roomNo: '1-102'}, {roomNo: '1-103'}],
				floor2: [{roomNo: '1-201'}, {roomNo: '1-202'}, {roomNo: '1-203'}],
				floor3: [{roomNo: '1-301'}, {roomNo: '1-302'}, {roomNo: '1-303'}]
			}
		}
	},
	hasNoFloor0: {
		evenFloors: {
			building3: {
				floor1: [{roomNo: '3-101'}, {roomNo: '3-102'}, {roomNo: '3-103'}],
				floor2: [{roomNo: '3-201'}, {roomNo: '3-202'}, {roomNo: '3-203'}],
				floor3: [{roomNo: '3-301'}, {roomNo: '3-302'}, {roomNo: '3-303'}],
				floor4: [{roomNo: '3-401'}, {roomNo: '3-402'}, {roomNo: '3-403'}]
			},
			building4: {},
		},
		oddFloors: {
			building2: {
				floor1: [{roomNo: '2-101'}, {roomNo: '2-102'}, {roomNo: '2-103'}],
				floor2: [{roomNo: '2-201'}, {roomNo: '2-202'}, {roomNo: '2-203'}],
				floor3: [{roomNo: '2-301'}, {roomNo: '2-302'}, {roomNo: '2-303'}]
			}
		}
	}
}
*/

const groupByHasFloor0ByArray = group(
	rooms,
	(parent, name, current) => current.floor0 ? 'hasFloor0' : 'hasNoFloor0',
	{
		type: Array,
		by: (parent, name, current) => Object.keys(current).length % 2
	}
);
/*
{
	hasFloor0: [
		{
			building1: {
				floor0: [{roomNo: '1-001'}, {roomNo: '1-002'}, {roomNo: '1-003'}],
				floor1: [{roomNo: '1-101'}, {roomNo: '1-102'}, {roomNo: '1-103'}],
				floor2: [{roomNo: '1-201'}, {roomNo: '1-202'}, {roomNo: '1-203'}],
				floor3: [{roomNo: '1-301'}, {roomNo: '1-302'}, {roomNo: '1-303'}]
			}
		}
	],
	hasNoFloor0: [
		{
			building3: {
				floor1: [{roomNo: '3-101'}, {roomNo: '3-102'}, {roomNo: '3-103'}],
				floor2: [{roomNo: '3-201'}, {roomNo: '3-202'}, {roomNo: '3-203'}],
				floor3: [{roomNo: '3-301'}, {roomNo: '3-302'}, {roomNo: '3-303'}],
				floor4: [{roomNo: '3-401'}, {roomNo: '3-402'}, {roomNo: '3-403'}]
			},
			building4: {},
		},
		{
			building2: {
				floor1: [{roomNo: '2-101'}, {roomNo: '2-102'}, {roomNo: '2-103'}],
				floor2: [{roomNo: '2-201'}, {roomNo: '2-202'}, {roomNo: '2-203'}],
				floor3: [{roomNo: '2-301'}, {roomNo: '2-302'}, {roomNo: '2-303'}]
			}
		}
	]
}
*/

redim

Change hierarchy dimension of an object.

Parameter definition:

redim(targetObject, ...hierarchyIndexes);
redim(targetObject, [hierarchyIndexes]);

The hierarchyIndex is the original depth of targetObject, starting from 0.

import { redim } from 'object-hierarchy-access';

const obj1 = {
	red: {
		wooden: {house: 'red wooden house', ship: 'red wooden ship'},
		iron: {house: 'red iron house', ship: 'red iron ship'},
		stone: {house: 'red stone house', ship: 'red stone ship'}
	},
	green: {
		wooden: {house: 'green wooden house', ship: 'green wooden ship'},
		iron: {house: 'green iron house', ship: 'green iron ship'},
		stone: {house: 'green stone house', ship: 'green stone ship'}
	},
	blue: {
		wooden: {house: 'blue wooden house', ship: 'blue wooden ship'},
		iron: {house: 'blue iron house', ship: 'blue iron ship'},
		stone: {house: 'blue stone house', ship: 'blue stone ship'}
	}
};
const result1 = redim(obj1, 1, 2, 0);
/*
{
	wooden: {
		house: {red: "red wooden house", green: "green wooden house", blue: "blue wooden house"},
		ship: {red: "red wooden ship", green: "green wooden ship", blue: "blue wooden ship"}
	},
	iron: {
		house: {red: "red iron house", green: "green iron house", blue: "blue iron house"},
		ship: {red: "red iron ship", green: "green iron ship", blue: "blue iron ship"}
	},
	stone: {
		house: {red: "red stone house", green: "green stone house", blue: "blue stone house"},
		ship: {red: "red stone ship", green: "green stone ship", blue: "blue stone ship"}
	}
}
*/

const obj2 = [
	{a: 1, b: 2, c: 3},
	{a: 10, b: 20, c: 30},
	{a: 100, b: 200, c:300},
];
const result2 = redim(obj2, 1, 0);
/*
{
	a: [1, 10, 100],
	b: [2, 20, 200],
	c: [3, 30, 300]
}
*/

Notice: The returned object's depth from 0 to Max(hierarchyIndexes) will be created as new objects. Thus values that reference to these hierarchies point to original hierarchies.