抱歉,我不知道如何标出问题标题。如果可能,请帮助编辑。
我有一个这样的对象:
{
a: 'jack',
b: {
c: 'sparrow',
d: {
e: 'hahaha'
}
}
}
我想让它看起来像:
{
'a': 'jack',
'b.c': 'sparrow',
'b.d.e': 'hahaha'
}
// so that I can use it this way:
a['b.d.e']
jQuery也可以。我知道对于嵌套对象,我可以使用a.b.d.e
来获取hahaha
,但今天我必须使用a['b.d.e']
-_- !!!
我怎样才能做到这一点?在此先感谢:)
答案 0 :(得分:18)
您可以使用递归函数来抓取对象并为您展平它。
var test = {
a: 'jack',
b: {
c: 'sparrow',
d: {
e: 'hahaha'
}
}
};
function dive(currentKey, into, target) {
for (var i in into) {
if (into.hasOwnProperty(i)) {
var newKey = i;
var newVal = into[i];
if (currentKey.length > 0) {
newKey = currentKey + '.' + i;
}
if (typeof newVal === "object") {
dive(newKey, newVal, target);
} else {
target[newKey] = newVal;
}
}
}
}
function flatten(arr) {
var newObj = {};
dive("", arr, newObj);
return newObj;
}
var flattened = JSON.stringify(flatten(test));
console.log(flattened);
答案 1 :(得分:4)
另一种递归实现。 我只想自己编写一个实现,即使当前的实现已经非常好。
递归函数检查密钥是否为'object'
类型。
function flat(res, key, val, pre = '') {
const prefix = [pre, key].filter(v => v).join('.');
return typeof val === 'object'
? Object.keys(val).reduce((prev, curr) => flat(prev, curr, val[curr], prefix), res)
: Object.assign(res, { [prefix]: val});
}
return Object.keys(input).reduce((prev, curr) => flat(prev, curr, input[curr]), {});
或者您可以简单地使用flat npm package,这是一个众所周知的测试库。
var flatten = require('flat')
flatten(obj);
⬑我会在严肃的代码中使用它。
function flatObject(input) {
function flat(res, key, val, pre = '') {
const prefix = [pre, key].filter(v => v).join('.');
return typeof val === 'object'
? Object.keys(val).reduce((prev, curr) => flat(prev, curr, val[curr], prefix), res)
: Object.assign(res, { [prefix]: val});
}
return Object.keys(input).reduce((prev, curr) => flat(prev, curr, input[curr]), {});
}
const result = flatObject(input);
http://codepen.io/zurfyx/pen/VpErja?editors=1010
function flatObject(input) {
function flat(res, key, val, pre = '') {
const prefix = [pre, key].filter(v => v).join('.');
return typeof val === 'object'
? Object.keys(val).reduce((prev, curr) => flat(prev, curr, val[curr], prefix), res)
: Object.assign(res, { [prefix]: val});
}
return Object.keys(input).reduce((prev, curr) => flat(prev, curr, input[curr]), {});
}
const result = flatObject({
a: 'jack',
b: {
c: 'sparrow',
d: {
e: 'hahaha'
}
}
});
document.getElementById('code').innerHTML = JSON.stringify(result, null, 2);
<pre><code id="code"></code></pre>
答案 2 :(得分:3)
递归是这种情况的最佳解决方案。
function flatten(input, reference, output) {
output = output || {};
for (var key in input) {
var value = input[key];
key = reference ? reference + '.' + key : key;
if (typeof value === 'object' && value !== null) {
flatten(value, key, output);
} else {
output[key] = value;
}
}
return output;
}
var result = flatten({
a: 'jack',
b: {
c: 'sparrow',
d: {
e: 'hahaha'
}
}
});
document.body.textContent = JSON.stringify(result);
&#13;
答案 3 :(得分:3)
您可以遍历对象的entries。如果value
是一个对象,则递归调用该函数。使用flatMap
获得扁平化的条目数组。
然后使用Object.fromEntries()
从扁平化的条目数组中获取对象
const input = {
a: 'jack',
b: {
c: 'sparrow',
d: {
e: 'hahaha'
}
}
}
const getEntries = (o, prefix = '') =>
Object.entries(o).flatMap(([k, v]) =>
Object(v) === v ? getEntries(v, `${prefix}${k}.`) : [ [`${prefix}${k}`, v] ]
)
console.log(
Object.fromEntries(getEntries(input))
)
注意:Object(v) === v
仅针对对象返回true
。 typeof v === 'object'
也适用于v = null
。
答案 4 :(得分:2)
最简单的算法。甚至容易记住:)
选项1:仅使用叶子导出平面对象。即,导出的对象仅包含末尾具有原始值的路径(请参见示例)。
//recursion: walk on each route until the primitive value.
//Did we found a primitive?
//Good, then join all keys in the current path and save it on the export object.
export function flatObject(obj) {
const flatObject = {};
const path = []; // current path
function dig(obj) {
if (obj !== Object(obj))
/*is primitive, end of path*/
return flatObject[path.join('.')] = obj; /*<- value*/
//no? so this is an object with keys. go deeper on each key down
for (let key in obj) {
path.push(key);
dig(obj[key]);
path.pop();
}
}
dig(obj);
return flatObject;
}
示例
let obj = {aaa:{bbb:{c:1,d:7}}, bb:{vv:2}}
console.log(flatObject(obj))
/*
{
"aaa.bbb.c": 1,
"aaa.bbb.d": 7,
"bb.vv": 2
}
*/
选项2:导出具有所有中间路径的平面对象。 有点短和简单(请参见示例)。
export function flatObject(obj) {
const flatObject = {};
const path = []; // current path
function dig(obj) {
for (let key in obj) {
path.push(key);
flatObject[path.join('.')] = obj[key];
dig(obj[key])
path.pop();
}
}
dig(obj);
return flatObject;
}
示例:
let obj = {aaa:{bbb:{c:1,d:7}}, bb:{vv:2}}
console.log(flatObject(obj))
/*{
"aaa": {
"bbb": {
"c": 1,
"d": 7
}
},
"aaa.bbb": {
"c": 1,
"d": 7
},
"aaa.bbb.c": 1,
"aaa.bbb.d": 7,
"bb": {
"vv": 2
},
"bb.vv": 2
}
*/
答案 5 :(得分:0)
具有递归函数的aproach,对对象的键的迭代以及如果值是对象的查找。如果是,请使用更新的功能拨打电话。否则将找到的值添加到结果对象。
function getValues(o, a) {
Object.keys(o).forEach(function (k) {
if (typeof o[k] === 'object') {
getValues(o[k], [].concat(a, k));
return;
}
result[[].concat(a, k).join('.')] = o[k];
});
}
var object = { a: 'jack', b: { c: 'sparrow', d: { e: 'hahaha' } } },
result = {};
getValues(object);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
&#13;
答案 6 :(得分:0)
仅举一个示例,如何使用ES6功能实现这一目标。
const flatObject = obj => {
const keys = Object.keys(obj)
return keys.reduce((acc, k) => {
const value = obj[k]
return typeof value === 'object' ?
{...acc, ...ObjectUtils.flatObject(value)} :
{...acc, [k]: value}
} , {})
}
答案 7 :(得分:0)
使用ES6的另一种方法。
const obj = {
a: "jack",
b: {
c: "sparrow",
d: {
e: "hahaha"
}
}
};
function flattenObj(value, currentKey) {
let result = {};
Object.keys(value).forEach(key => {
const tempKey = currentKey ? `${currentKey}.${key}` : key;
if (typeof value[key] !== "object") {
result[tempKey] = value[key];
} else {
result = { ...result, ...flattenObj(value[key], tempKey) };
}
});
return result;
}
console.log(flattenObj(obj));
答案 8 :(得分:0)
var flattenObject = function(ob) {
var toReturn = {};
for (var i in ob) {
if (!ob.hasOwnProperty(i)) continue;
if ((typeof ob[i]) == 'object' && ob[i] !== null) {
var flatObject = flattenObject(ob[i]);
for (var x in flatObject) {
if (!flatObject.hasOwnProperty(x)) continue;
toReturn[i + '.' + x] = flatObject[x];
}
} else {
toReturn[i] = ob[i];
}
}
console.log(toReturn)
return toReturn;
};
var ob = {
'a': {
'b': {
'b2': 2
},
'c': {
'c2': 2,
'c3': 3
}
}
};
flattenObject(ob);
答案 9 :(得分:0)
const flatten = function(obj) {
const result = {};
for (let key in obj) {
if (typeof obj[key] === 'object') {
const childObj = flatten(obj[key]);
for (let childObjKey in childObj) {
result[`${key}.${childObjKey}`] = childObj[childObjKey];
}
} else {
result[key] = obj[key];
}
}
return result
}
var test = {
a: 'jack',
b: {
c: 'sparrow',
d: {
e: 'hahaha'
}
}
};
console.log(flatten(test));
答案 10 :(得分:-1)
尝试一下
const result = [].concat.apply([], parentArray.map((item: any) => item.any)