Javascript 一个用于展平嵌套对象的线条
我需要展平嵌套对象。我需要一个班轮。不确定这个过程的正确术语是什么。 我可以使用纯Javascript或库,我特别喜欢下划线 我有Javascript 一个用于展平嵌套对象的线条,javascript,underscore.js,Javascript,Underscore.js,我需要展平嵌套对象。我需要一个班轮。不确定这个过程的正确术语是什么。 我可以使用纯Javascript或库,我特别喜欢下划线 我有 { a:2, b: { c:3 } } 我想要 { a:2, c:3 } 我试过 var obj = {"fred":2,"jill":4,"obby":{"john":5}}; var resultObj = _.pick(obj, "fred") alert(JSON.stringify(resultObj)); 这很管用,但我
{
a:2,
b: {
c:3
}
}
我想要
{
a:2,
c:3
}
我试过
var obj = {"fred":2,"jill":4,"obby":{"john":5}};
var resultObj = _.pick(obj, "fred")
alert(JSON.stringify(resultObj));
这很管用,但我也需要这个
var obj = {"fred":2,"jill":4,"obby":{"john":5}};
var resultObj = _.pick(obj, "john")
alert(JSON.stringify(resultObj));
这是我在公共库中使用的函数,正是为了这个目的。 我相信我是从一个类似的stackoverflow问题中得到这个答案的,但我记不起是哪个了(编辑:-谢谢Yoshi!) 您还可以将此函数附加到标准Javascript字符串类,如下所示:
var myJSON = '{a:2, b:{c:3}}';
var myFlattenedJSON = flatten(myJSON);
String.prototype.flattenJSON = function() {
var data = this;
var result = {};
function recurse (cur, prop) {
if (Object(cur) !== cur) {
result[prop] = cur;
} else if (Array.isArray(cur)) {
for(var i=0, l=cur.length; i<l; i++)
recurse(cur[i], prop + "[" + i + "]");
if (l == 0)
result[prop] = [];
} else {
var isEmpty = true;
for (var p in cur) {
isEmpty = false;
recurse(cur[p], prop ? prop+"."+p : p);
}
if (isEmpty && prop)
result[prop] = {};
}
}
recurse(data, "");
return result;
}
给你:
Object.assign({}, ...function _flatten(o) { return [].concat(...Object.keys(o).map(k => typeof o[k] === 'object' ? _flatten(o[k]) : ({[k]: o[k]})))}(yourObject))
摘要:递归创建一个包含一个属性对象的数组,然后将它们与对象组合。分配
((o) => {
return o !== Object(o) || Array.isArray(o) ? {}
: Object.assign({}, ...function leaves(o) {
return [].concat.apply([], Object.entries(o)
.map(([k, v]) => {
return (( !v || typeof v !== 'object'
|| !Object.keys(v).some(key => v.hasOwnProperty(key))
|| Array.isArray(v))
? {[k]: v}
: leaves(v)
);
})
);
}(o))
})(o)
这使用了ES6功能,包括Object.assign
或spread操作符,但重写应该很容易,不需要它们
对于那些不在乎一行文字的疯狂,并且希望能够真正阅读的人(取决于你对可读性的定义):
这并不是一个简单的解决方案,但是这里有一个解决方案,它不需要来自ES6的任何东西。它使用下划线的extend
方法,该方法可以替换为jQuery
function flatten(obj) {
var flattenedObj = {};
Object.keys(obj).forEach(function(key){
if (typeof obj[key] === 'object') {
$.extend(flattenedObj, flatten(obj[key]));
} else {
flattenedObj[key] = obj[key];
}
});
return flattenedObj;
}
这里有一些普通的解决方案,它们适用于数组、原语、正则表达式、函数、任意数量的嵌套对象级别,以及我可以向它们抛出的所有其他东西。第一个将以您期望的方式从Object.assign
覆盖属性值
((o) => {
return o !== Object(o) || Array.isArray(o) ? {}
: Object.assign({}, ...function leaves(o) {
return [].concat.apply([], Object.entries(o)
.map(([k, v]) => {
return (( !v || typeof v !== 'object'
|| !Object.keys(v).some(key => v.hasOwnProperty(key))
|| Array.isArray(v))
? {[k]: v}
: leaves(v)
);
})
);
}(o))
})(o)
第二个将值累加到一个数组中
((o) => {
return o !== Object(o) || Array.isArray(o) ? {}
: (function () {
return Object.values((function leaves(o) {
return [].concat.apply([], !o ? [] : Object.entries(o)
.map(([k, v]) => {
return (( !v || typeof v !== 'object'
|| !Object.keys(v).some(k => v.hasOwnProperty(k))
|| (Array.isArray(v) && !v.some(el => typeof el === 'object')))
? {[k]: v}
: leaves(v)
);
})
);
}(o))).reduce((acc, cur) => {
return ((key) => {
acc[key] = !acc[key] ? [cur[key]]
: new Array(...new Set(acc[key].concat([cur[key]])))
})(Object.keys(cur)[0]) ? acc : acc
}, {})
})(o);
})(o)
另外,请不要在生产中包含这样的代码,因为调试非常困难
函数离开1(o){
返回((o)=>{
返回o!==Object(o)| | Array.isArray(o){
:Object.assign({},…函数离开(o){
返回[].concat.apply([],Object.entries(o)
.map([k,v])=>{
返回((!v | | typeof v!=='object'
||!Object.keys(v).some(key=>v.hasOwnProperty(key))
||数组。isArray(v))
?{[k]:v}
:树叶(v)
);
})
);
}(o) )
})(o) );
}
函数2(o){
返回((o)=>{
返回o!==Object(o)| | Array.isArray(o){
:(函数(){
返回Object.values((函数离开(o)){
返回[].concat.apply([],!o?[]:Object.entries(o)
.map([k,v])=>{
返回((!v | | typeof v!=='object'
||!Object.key(v.some)(k=>v.hasOwnProperty(k))
||(Array.isArray(v)和&&!v.some(el=>typeof el=='object'))
?{[k]:v}
:树叶(v)
);
})
);
}(o) )。减少((acc,cur)=>{
返回((键)=>{
acc[键]=!acc[键]?[当前[键]]
:新数组(…新集合(acc[key].concat([cur[key]]))
})(对象键(cur)[0])?acc:acc
}, {})
})(o) );
})(o) );
}
常量对象={
l1k0:‘foo’,
l1k1:{
l2k0:'酒吧',
l2k1:{
l3k0:{},
l3k1:null
},
l2k2:未定义
},
l1k2:0,
l2k3:{
l3k2:是的,
l3k3:{
l4k0:[1,2,3],
l4k1:[4,5,'six',{7:'eight'}],
l4k2:{
null:'测试',
[{}]:'obj',
[Array.prototype.map]:Array.prototype.map,
l5k3:((o)=>(o的类型=='object'))(this.obj),
}
}
},
l1k4:“”,
l1k5:新的RegExp(/[\s\t]+/g),
l1k6:函数(o){返回o.reduce((a,b)=>a+b)},
错误:[],
}
常量objs=[null,未定义,{},[],['non',empty'],42,/[\s\t]+/g,obj];
objs.forEach(o=>{
控制台日志(1(o));
});
objs.forEach(o=>{
控制台日志(leves2(o));
});代码>
演示
简化可读示例,无依赖项
/**
*展平多维对象
*
*例如:
*扁平对象({a:1,b:{c:2})
*返回:
*{a:1,c:2}
*/
导出常量对象=(对象)=>{
常数展平={}
Object.keys(obj.forEach)((key)=>{
if(对象[键]==='object'&&obj[键]!==null的类型){
赋值(展平,展平对象(obj[key]))
}否则{
展平[键]=对象[键]
}
})
回程变平
}
工作示例:我喜欢这段代码,因为它更容易理解
编辑:我添加了一些我需要的功能,所以现在更难理解了
const数据={
a:“a”,
b:{
c:“c”,
d:{
e:“e”,
f:[
“g”,
{
我:“我”,
j:{},
k:[]
}
]
}
}
};
函数展平(数据,响应={},flatKey=“”,onlyLastKey=false){
for(对象项(数据)的常量[键,值]){
让新的FlatKey;
if(!isNaN(parseInt(key))&&flatKey.includes(“[]”){
newFlatKey=(flatKey.charAt(flatKey.length-1)=“?.flatKey.slice(0,-1):flatKey)+`[${key}]`;
}如果(!flatKey.includes(“.”&&flatKey.length>0),则为else{
newFlatKey=`${flatKey}.${key}`;
}否则{
newFlatKey=`${flatKey}${key}`;
}
if(typeof value==“object”&&value!==null&&object.keys(value).length>0){
展平(值,响应,`${newFlatKey}.`,onlyLatKey);
}否则{
如果(仅限LASTKEY){
newFlatKey=newFlatKey.split(“.”.pop();
}
if(Array.isArray(响应)){
响应推送({
[newFlatKey.replace(“[]”,“”)]:值
});
}否则{
响应[newFlatKey.replace(“[]”,“”))]=值;
}
}
}
返回响应;
}
console.log(展平(数据));
log(展平(数据,{},“数据”);
log(展平(数据,{},“数据[]”);
log(展平(data,{},“data”,true));
log(展平(data,{},“data[]”,true);
log(展平(数据,[]);
log(展平(数据,[],“数据”);
log(展平(数据,[],“数据[]”);
log(展平(数据,[],“数据”,true));
console.log(展平(数据,[],
((o) => {
return o !== Object(o) || Array.isArray(o) ? {}
: Object.assign({}, ...function leaves(o) {
return [].concat.apply([], Object.entries(o)
.map(([k, v]) => {
return (( !v || typeof v !== 'object'
|| !Object.keys(v).some(key => v.hasOwnProperty(key))
|| Array.isArray(v))
? {[k]: v}
: leaves(v)
);
})
);
}(o))
})(o)
((o) => {
return o !== Object(o) || Array.isArray(o) ? {}
: (function () {
return Object.values((function leaves(o) {
return [].concat.apply([], !o ? [] : Object.entries(o)
.map(([k, v]) => {
return (( !v || typeof v !== 'object'
|| !Object.keys(v).some(k => v.hasOwnProperty(k))
|| (Array.isArray(v) && !v.some(el => typeof el === 'object')))
? {[k]: v}
: leaves(v)
);
})
);
}(o))).reduce((acc, cur) => {
return ((key) => {
acc[key] = !acc[key] ? [cur[key]]
: new Array(...new Set(acc[key].concat([cur[key]])))
})(Object.keys(cur)[0]) ? acc : acc
}, {})
})(o);
})(o)
function flatten(obj: any) {
return Object.keys(obj).reduce((acc, current) => {
const key = `${current}`;
const currentValue = obj[current];
if (Array.isArray(currentValue) || Object(currentValue) === currentValue) {
Object.assign(acc, flatten(currentValue));
} else {
acc[key] = currentValue;
}
return acc;
}, {});
};
let obj = {
a:2,
b: {
c:3
}
}
console.log(flatten(obj))
loopValues(val){
let vals = Object.values(val);
let q = [];
vals.forEach(elm => {
if(elm === null || elm === undefined) { return; }
if (typeof elm === 'object') {
q = [...q, ...this.loopValues(elm)];
}
return q.push(elm);
});
return q;
}
let flatValues = this.loopValues(object)
flatValues = flatValues.filter(elm => typeof elm !== 'object');
console.log(flatValues);
let resObj = {};
function flattenObj(obj) {
for (let key in obj) {
if (!(typeof obj[key] == 'object')) {
// console.log('not an object', key);
resObj[key] = obj[key];
// console.log('res obj is ', resObj);
} else {
flattenObj(obj[key]);
}
}
return resObj;
}
private flattenObject(obj: any): any {
const flattened = {};
for (const key of Object.keys(obj)) {
if (isNullOrUndefined(obj[key])) {
continue;
}
if (typeof obj[key].getMonth === 'function') {
flattened[key] = (obj[key] as Date).toISOString();
} else if (typeof obj[key] === 'object' && obj[key] !== null) {
Object.assign(flattened, this.flattenObject(obj[key]));
} else {
flattened[key] = obj[key];
}
}
return flattened;
}