I have written this small function to get all keys and values of an object and store them into an array. The object might contain arrays as values...
Object {
The function below will flatten an object to the specified depth. This function uses a loop rather than recursion. You can choose how child property keys are named, the default is 'parent.child'. The result is an array of [key, value]
arrays, like Object.entries()
. It requires lodash for isPlainObject
and partition()
, though you could write your own isPlainObject, partition functions if you wanted to remove the dependency.
/**
* Returns an array containing the properties of the given Object in the same format
* as Object.entries(). Goes through child objects to the specified depth,
* flattening the properties and prefixing child keys with a parent key names.
* @param {Object} object to retrieve property values for
* @param {Number} maxDepth the maximum number of times to look at properties of
* properties of the given object.
* Set to 1 to only retrieve the property values of the given object, 2 to get
* properties and sub-properties etc.
* @param {Function} keyPrefixer a function that takes a parent object name, and
* a child object name and returns a string representing the combined name.
* @returns {Array} containing the properties and child properties of the given object.
* Each property is returned as an array [key, value].
* Returns an empty array if object is null, undefined, not-an-object, or empty.
*/
const flattenEntries = (
object,
maxDepth = 2,
keyPrefixer = (parentKey, childKey) => `${parentKey}.${childKey}`) => {
if (!object || !_.isPlainObject(object)) {
return [];
}
// make maxDepth >= 1
maxDepth = Math.max(1, Math.abs(maxDepth));
const entryIsNotAnObject = ([key, val]) => !_.isPlainObject(val);
let [simpleProperties, childObjects] = _.partition(Object.entries(object), entryIsNotAnObject);
let result = simpleProperties;
for (let depth = 1; depth < maxDepth; depth++) {
for (let [childObjectKey, childObject] of childObjects) {
const entries = Object.entries(childObject);
const addParentPrefixToKey = ([key, val]) => [keyPrefixer(childObjectKey, key), val];
const prefixedEntries = entries.map(addParentPrefixToKey);
[simpleProperties, childObjects] = _.partition(prefixedEntries, entryIsNotAnObject);
result = result.concat(simpleProperties);
}
}
return result;
};
const test = {
a: 'one',
b: {
c: 'three',
d: {
e: {
f: ['six', 'six'],
g: 7
}
}
}
};
console.log(flattenEntries(test, 10));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
You can skip the inner loop if you have to push contents of an array to another array. See if this helps --
function flattenObject(obj) {
// Returns array with all keys and values of an object
var array = [];
$.each(obj, function (key, value) {
array.push(key);
if ($.isArray(value)) {
Array.prototype.push.apply(array, value);
}
else {
array.push(value);
}
});
return array;
}
var obj = {"key1" : [1,3,3],"key2" : "val", "key3":23};
var output = flattenObject(obj);
console.log(output);
Fiddle Link -- https://jsfiddle.net/0wu5z79a/1/
EDIT : This solution is valid only for your scenario where you know that the nesting is till one level only else you need to have some recursion for deep inner objects.
I needed something really simple and here is a one-liner I came up with:
function flatten(obj){
return Object.values(obj).flat()
}
Obviously, this is subject to your browser/JS env supporting this syntax. Here is a working example.
const flatten=(obj)=>Object.values(obj).flat()
const x={x:[1,2,3],y:[4,5,6,7]}
console.log(flatten(x))
If you're feeling really lazy then you can make use of the popular NPM library flat.
Example (from their docs)
var flatten = require('flat')
flatten({
key1: {
keyA: 'valueI'
},
key2: {
keyB: 'valueII'
},
key3: { a: { b: { c: 2 } } }
})
// {
// 'key1.keyA': 'valueI',
// 'key2.keyB': 'valueII',
// 'key3.a.b.c': 2
// }