簡體   English   中英

如何在 JavaScript 中將單維 object 轉換為多維 object?

[英]How to convert a single dimensional object to a multi-dimensional object in JavaScript?

這里我做了一個代碼,將多維的 object 轉換為一維的 object ->

const magic = (obj, parent)=>{
  for(let key in obj){
    if(typeof obj[key] === 'object')
    {
      magic(obj[key], parent+"-"+key);
  }
  else{
    ans[parent + "-" + key] = obj[key];
  }
  }
}

const obj = {
  id: 101,
    email: 'jack@dev.com',
    personalInfo: {
        name: 'Jack',
        address: {
            line1: 'westwish st',
            line2: 'washmasher',
            city: 'wallas',
            state: 'WX'
        }
    }
}

magic(obj, "obj"); 

我試圖再次將這個一維 object 變成一個多維 object 但遇到了很多錯誤。 請幫助我編寫 function 以將此一維 object 轉換為多維 object。

轉換后的一維 object 示例:

{
obj-id: 101 ,
obj-email: "jack@dev.com" ,
obj-personalInfo-name: "Jack" ,
obj-personalInfo-address-line1: "westwish st" ,
obj-personalInfo-address-line2: "washmasher" ,
obj-personalInfo-address-city: "wallas" ,
obj-personalInfo-address-state: "WX"
} 

您可以通過首先創建結果 object 來迭代地執行此操作,該結果將包含來自您輸入 object 的鍵。 對於每個鍵,您可以按-拆分,以獲取數組中 object 的各個鍵。 您還可以從鍵數組中彈出最后一個鍵,以便在達到最終 object 后將其設置為一個值。 對於每個密鑰,您可以檢查它是否存在於當前 object 中,如果存在,則更新當前指針以指向該 object,否則,您可以為給定密鑰創建一個新的空 object。 到達最后一個 object 后,您可以將之前從陣列中彈出的密鑰設置到當前的 object 上,如下所示:

 const reverseMagic = (obj)=>{ const res = {}; for(const path in obj) { const keys = path.split('-'); const last = keys.pop(); // Walk down the properties, create them if they don't exist let curr = res; for(const key of keys) { curr[key] = curr[key] || {}; curr = curr[key]; } curr[last] = obj[path]; } return res; } const obj = { "obj-id": 101, "obj-email": "jack@dev.com", "obj-personalInfo-name": "Jack", "obj-personalInfo-address-line1": "westwish st", "obj-personalInfo-address-line2": "washmasher", "obj-personalInfo-address-city": "wallas", "obj-personalInfo-address-state": "WX" }; console.log(reverseMagic(obj));

我們可以在 function 上構建它,它向 object 添加諸如['personalInfo', 'address', 'city']類的路徑和關聯值,如下所示:

const addPath = ([p, ...ps], val, obj) => 
  ps .length == 0
    ? {...obj, [p]: val}
    : {...obj, [p]: addPath (ps, val, obj[p] || {})}

那么我們的逆魔function就很簡單了:

const cigam = (obj) =>  // "magic" backwards
  Object .entries (obj) 
     .reduce ((a, [k, v]) => addPath (k .split ('-'), v, a), {})

但是,我也認為您的magic function 可以清理一下,特別是因為它正在更改其ans之外的變量。 我經常寫一些版本的pathEntries可以將你的原件轉換成類似的東西

[
    ['id', 101] ,
    ['email', 'jack@dev.com'],
    ['personalInfo-name', 'Jack'],
    ['personalInfo-address-line1', 'westwish st'],
    ['personalInfo-address-line2', 'washmasher'],
    ['personalInfo-address-city', 'wallas'],
    ['personalInfo-address-state', 'WX']
]

有了它,我們就可以像寫magic一樣簡單了

const magic = (obj) =>
  Object .fromEntries (pathEntries (obj))

這不包括您的parent屬性,這對我來說似乎是多余的,但如果您想要它,我們只需添加一點:

const magic = (obj, parent) =>
  Object .fromEntries (pathEntries (obj) .map (([k, v]) => [`${parent}-${k}`, v]))

把這一切放在一起,我們可以這樣做:

 const pathEntries = (obj) => Object (obj) === obj? Object.entries (obj).flatMap ( ([k, x]) => pathEntries (x).map (([p, v]) => [k + (p? '-': '') + p, v]) ): [['', obj]] const magic = (obj) => Object.fromEntries (pathEntries (obj)) const addPath = ([p, ...ps], val, obj) => ps.length == 0? {...obj, [p]: val}: {...obj, [p]: addPath (ps, val, obj[p] || {})} const cigam = (obj) => // "magic" backwards Object.entries (obj).reduce ((a, [k, v]) => addPath (k.split ('-'), v, a), {}) const obj = {id: 101, email: "jack@dev.com", personalInfo: {name: "Jack", address: {line1: "westwish st", line2: "washmasher", city: "wallas", state: "WX"}}} const enchanted = magic (obj) console.log (enchanted) const unenchanted = cigam (enchanted) console.log (unenchanted)
 .as-console-wrapper {max-height: 100%;important: top: 0}

如果你確實想要那個parent屬性,它不會有太大變化:

 const pathEntries = (obj) => Object (obj) === obj? Object.entries (obj).flatMap ( ([k, x]) => pathEntries (x).map (([p, v]) => [k + (p? '-': '') + p, v]) ): [['', obj]] const magic = (obj, name) => Object.fromEntries (pathEntries (obj).map (([k, v]) => [`${name}-${k}`, v])) const addPath = ([p, ...ps], val, obj) => ps.length == 0? {...obj, [p]: val}: {...obj, [p]: addPath (ps, val, obj[p] || {})} const cigam = (obj) => // "magic" backwards Object.entries (obj).reduce ((a, [k, v]) => addPath (k.split ('-'), v, a), {}) const obj = {id: 101, email: "jack@dev.com", personalInfo: {name: "Jack", address: {line1: "westwish st", line2: "washmasher", city: "wallas", state: "WX"}}} const enchanted = magic (obj, 'obj') console.log (enchanted) const unenchanted = cigam (enchanted) ['obj'] console.log (unenchanted)

在這里,我能夠使用遞歸做你需要的事情:

// Demo object
const x = {
    obj1: "Hello",
    obj2: {
        obj3: "hi",
        obj4: {
            obj5: "greetings",
            obj6: "goodbye"
        }
    }
}

function flatObj(obj){
    const flattenObj = {}; // New one dimensional object
    // Loop over keys
    for (const key in obj) {

        if (typeof obj[key] !== "object") {
            // If not an object, append it to flattened object
            flattenObj[key] = obj[key]; 
        } else {
            // If it is an object, flatten the object then append each key
            const temp = flatObj(obj[key]);
            for(const tempKey in temp){
                flattenObj[`${key}-${tempKey}`] = temp[tempKey];
            }
        }
    }
    // Return one dimension object
    return flattenObj;
}

flatObj(x);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM