I have stuck at a point where I want to recursively traverse all the objects in an array and get the keys of those objects in a array data structure. I know how to loop over and get the keys of the object. But the problem here is I need that recursively for flexible objects. By flexible I mean it can have any level of nested properties.
我一直想要以递归方式遍历数组中的所有对象,并在数组数据结构中获取这些对象的键。我知道如何循环并获取对象的键。但这里的问题是我需要递归地为灵活的对象。灵活的我的意思是它可以有任何级别的嵌套属性。
So, what I have is an array like this:
所以,我有一个这样的数组:
let record = [{
"province": "string",
"city": "string",
"type": "alternative_address",
"address_line1": "string",
"post_code": "5858"
},
{
"province": "string",
"city": "string",
"type": "alternative_address",
"post_code": "5858",
"embedeer": {
"veryEmbedded": {
"veryveryEmbeded": 'yes'
}
}
}
];
And with some computation I am expecting an output like:
通过一些计算,我期待输出如下:
['province','city','type','address_line1','post_code','embedeer', 'embedeer.veryEmbedded', 'embedeer.veryEmbedded.veryveryEmbeded'];
For the effort I tried on this, I used the reduce()
operation on array but I am unable to get that.
对于我尝试过的努力,我在数组上使用了reduce()操作但是我无法得到它。
4 个解决方案
#1
2
You need to write a recursive function that takes 2 inputs
您需要编写一个需要2个输入的递归函数
- object
- prefix (undefined for first level keys)
前缀(未定义为第一级键)
let record = [{"province":"string","city":"string","type":"alternative_address","address_line1":"string","post_code":"5858"},{"province":"string","city":"string","type":"alternative_address","post_code":"5858","embedeer":{"veryEmbedded":{"veryveryEmbeded":"yes"}}}];
function addKeysToSet(o, p) {
Object.keys(o).forEach(k => {
let key = p ? p + "." + k : k; // Create the key hierarchy
keys.add(key); // Add key to the set
// If the value is an object, call the function recursively
if(typeof o[k] === 'object') {
addKeysToSet(o[k], key);
}
});
}
let keys = new Set(); // Create set of unique keys
// For each object in array, call function that adds keys to the set
record.forEach(o => addKeysToSet(o));
let result = Array.from(keys); // Create array from set
console.log(result); // logs result
#2
1
You could take an iterative and recursive approach and take the power of a Set
for getting unique values.
您可以采用迭代和递归方法,并获取Set的强大功能以获取唯一值。
function iter(object, keys) {
return Object
.entries(object)
.reduce((r, [k, v]) => r.concat(keys.concat(k).join('.'), v && typeof v === 'object'
? iter(v, keys.concat(k))
: []
), []);
}
var record = [{ province: "string", city: "string", type: "alternative_address", address_line1: "string", post_code: "5858" }, { province: "string", city: "string", type: "alternative_address", post_code: "5858", embedeer: { veryEmbedded: { veryveryEmbeded: 'yes' } } }],
keys = [...record.reduce((s, o) => iter(o, []).reduce((t, v) => t.add(v), s), new Set)];
console.log(keys);
.as-console-wrapper { max-height: 100% !important; top: 0; }
#3
0
You can Flatten the object and then get the keys.
您可以展平对象然后获取密钥。
// form https://gist.github.com/penguinboy/762197
let record = [{"province":"string","city":"string","type":"alternative_address","address_line1":"string","post_code":"5858"},{"province":"string","city":"string","type":"alternative_address","post_code":"5858","embedeer":{"veryEmbedded":{"veryveryEmbeded":"yes"}}}];
var flattenObject = function(a) {
var b = {};
for (var c in a)
if (a.hasOwnProperty(c))
if ("object" == typeof a[c]) {
var d = flattenObject(a[c]);
for (var e in d) d.hasOwnProperty(e) && (b[c + "." + e] = d[e]);
} else b[c] = a[c];
return b;
};
console.log(flattenObject(record) )
/*
It is also taking care of index numbers of the array. ("0.province" instead of "province" If multiple entries are passed)
*/
console.info( "All keys", Object.keys(flattenObject(record) ) )
// Simple
console.info( "keys", Object.keys(flattenObject(record[1]) ) )
#4
0
var record1 = [{"province": "string","city": "string","type": "alternative_address","address_line1": "string","post_code": "5858" },
{ "province": "string","city": "string",
"type": "alternative_address",
"post_code": "5858",
"embedeer": {
"veryEmbedded": {
"veryveryEmbeded": 'yes'
}
}
}
];
var output = [];
function getAllKeys(obj,precedor="") {
var temp = Object.entries(obj);
temp.forEach((el) =>
typeof el[1] == "object" ? ( output.push(el[0]),getAllKeys(el[1],precedor==""? el[0]: precedor+"."+el[0])): output.push(precedor==""? el[0]: precedor+"."+el[0]));
}
record1.forEach((el,i) => getAllKeys(el,""));
//To avoid duplicate entries convert array to object.
console.log(...(new Set(output)));
#1
2
You need to write a recursive function that takes 2 inputs
您需要编写一个需要2个输入的递归函数
- object
- prefix (undefined for first level keys)
前缀(未定义为第一级键)
let record = [{"province":"string","city":"string","type":"alternative_address","address_line1":"string","post_code":"5858"},{"province":"string","city":"string","type":"alternative_address","post_code":"5858","embedeer":{"veryEmbedded":{"veryveryEmbeded":"yes"}}}];
function addKeysToSet(o, p) {
Object.keys(o).forEach(k => {
let key = p ? p + "." + k : k; // Create the key hierarchy
keys.add(key); // Add key to the set
// If the value is an object, call the function recursively
if(typeof o[k] === 'object') {
addKeysToSet(o[k], key);
}
});
}
let keys = new Set(); // Create set of unique keys
// For each object in array, call function that adds keys to the set
record.forEach(o => addKeysToSet(o));
let result = Array.from(keys); // Create array from set
console.log(result); // logs result
#2
1
You could take an iterative and recursive approach and take the power of a Set
for getting unique values.
您可以采用迭代和递归方法,并获取Set的强大功能以获取唯一值。
function iter(object, keys) {
return Object
.entries(object)
.reduce((r, [k, v]) => r.concat(keys.concat(k).join('.'), v && typeof v === 'object'
? iter(v, keys.concat(k))
: []
), []);
}
var record = [{ province: "string", city: "string", type: "alternative_address", address_line1: "string", post_code: "5858" }, { province: "string", city: "string", type: "alternative_address", post_code: "5858", embedeer: { veryEmbedded: { veryveryEmbeded: 'yes' } } }],
keys = [...record.reduce((s, o) => iter(o, []).reduce((t, v) => t.add(v), s), new Set)];
console.log(keys);
.as-console-wrapper { max-height: 100% !important; top: 0; }
#3
0
You can Flatten the object and then get the keys.
您可以展平对象然后获取密钥。
// form https://gist.github.com/penguinboy/762197
let record = [{"province":"string","city":"string","type":"alternative_address","address_line1":"string","post_code":"5858"},{"province":"string","city":"string","type":"alternative_address","post_code":"5858","embedeer":{"veryEmbedded":{"veryveryEmbeded":"yes"}}}];
var flattenObject = function(a) {
var b = {};
for (var c in a)
if (a.hasOwnProperty(c))
if ("object" == typeof a[c]) {
var d = flattenObject(a[c]);
for (var e in d) d.hasOwnProperty(e) && (b[c + "." + e] = d[e]);
} else b[c] = a[c];
return b;
};
console.log(flattenObject(record) )
/*
It is also taking care of index numbers of the array. ("0.province" instead of "province" If multiple entries are passed)
*/
console.info( "All keys", Object.keys(flattenObject(record) ) )
// Simple
console.info( "keys", Object.keys(flattenObject(record[1]) ) )
#4
0
var record1 = [{"province": "string","city": "string","type": "alternative_address","address_line1": "string","post_code": "5858" },
{ "province": "string","city": "string",
"type": "alternative_address",
"post_code": "5858",
"embedeer": {
"veryEmbedded": {
"veryveryEmbeded": 'yes'
}
}
}
];
var output = [];
function getAllKeys(obj,precedor="") {
var temp = Object.entries(obj);
temp.forEach((el) =>
typeof el[1] == "object" ? ( output.push(el[0]),getAllKeys(el[1],precedor==""? el[0]: precedor+"."+el[0])): output.push(precedor==""? el[0]: precedor+"."+el[0]));
}
record1.forEach((el,i) => getAllKeys(el,""));
//To avoid duplicate entries convert array to object.
console.log(...(new Set(output)));