将对象字段转换为对象数组

Convert Object Fields to an Array of Object

我正在调用一个身份验证 API returns 一个 Observable<any> 对象是:

name: "John"
role: "Admin"

响应可以有一些变化:

  1. 可以存在额外的字段;

  2. 如果一个字段的值多于它 returns 一个数组:

    email: "john@example.com"   // 1. Extra Field 
    name: "John"  
    role: ["Admin", "Editor"]   // 2. Field now gets 2 values
    

我创建了一个界面:

export class Claim {
  type: string;
  value: string;
}

如何从对象创建声明数组?

对于第一个示例,声明数组将是:

type      value
  
name      John
role      Admin

对于第二个示例,声明数组将是:

type      value 
  
email     john@example.com
name      John
role      Admin
role      Tutor         // An array would expand into multiple Claims of same type

更新

根据 pc_coder 回答我有以下内容:

getClaims(type: string): Observable<Claim[]> {

  return this.getUser().pipe(map(user => {

    let claims: Claim[] = [];

    Object.entries(user.profile).forEach((element)=>{ 
      if (typeof element[1] == "object") { 
        element[1].forEach(x => { 
          claims.push({ type: element[0], value: x })
        })
      }
      else { 
        claims.push({ type: element[0], value: element[1]})
      }   
    });

    return claims;

  }));

}
 

应该或可以使用 RXJS 运算符进行转换吗?

如果 getClaimstype 参数不为空,我可以按类型过滤声明吗?

使用 Object.keysObject.entries 您可以访问键名,然后访问值。检查值对象是否然后推送到新对象数组

var obj1={email: "john@example.com",name: "John" ,role: ["Admin", "Editor"] }
var obj2={email: "john@example.com",name: "John"  }

//with Object.keys
function convertTo(obj){
  var result=[];
  Object.keys(obj).forEach((el)=>{
    if(typeof obj[el]=="object"){obj[el].forEach(x=>{result.push({type:el,value:x})})}
    else{ result.push({type:el,value:obj[el]})}
  })
  return result;
}
//with Object.entries

function convertTo2(obj){
  var result=[];
  Object.entries(obj).forEach((el)=>{ 
    if(typeof el[1]=="object"){ el[1].forEach(x=>{result.push({type:el[0],value:x})})}
    else{ result.push({type:el[0],value:el[1]})}   
  });
  return result;
}
console.log(convertTo2(obj1));console.log(convertTo2(obj2));console.log(convertTo(obj1));console.log(convertTo(obj2));

尝试

function toClaims(data: {[key:string]: string|string[]}):Claim[]{
    const result=new Array();
    for(const type in data){
        if(data.hasOwnProperty(type)){
            const element = data[type];
            if(Array.isArray(element)){
                for(const value of element){
                    result.push({
                        type,
                        value,
                    });
                }
            } else{
                result.push({
                    type,
                    value: element,
                });
            }
        }
    }
    return result;
}