簡體   English   中英

Javascript:嵌套對象引用的點符號字符串

[英]Javascript: Dot Notation Strings to Nested Object References

我們試圖基於點表示法字符串設置嵌套對象的值。

輸入示例:

{
    "bowtime": [
       "30",
       " 1",
       " 3",
       " 20"
    ],
    "bowstate.levi.leviFlo.totalFloQuot": ".95",
    "bowstate.crem.cremQuot": "79" 
}

所需的輸出:

{
    "bowstate": {
       "levi": {
           "leviFlo": {
               "totalFloQuot": 0.95
           }
       },
       "crem": {
           "cremQuot": 79
       }
    },
    "bowtime": [
       "30",
       " 1",
       " 3",
       " 20"
    ],
}

到目前為止,代碼可以正常工作,但看起來過於復雜,並且僅允許4層嵌套。 我們如何簡化此代碼,並使它適用於具有四層以上嵌套的引用:

const dayspace = {};
var keyArr = Object.keys(input);

for (key in keyArr) {
  if ( keyArr[key].indexOf('.') > -1 ) {
    var setArr = keyArr[key].split('.');
    dayspace[setArr[0]] = dayspace[setArr[0]] || {}
    for (var s = 0; s < setArr.length; s++) {
      if (s == 1) {
        if (setArr.length > s + 1) dayspace[setArr[0]][setArr[s]] = {}
        else dayspace[setArr[0]][setArr[s]] = req.body[keyArr[key]]
      }
      if (s == 2) {
        if (setArr.length > s + 1) dayspace[setArr[0]][setArr[1]][setArr[s]] = {}
        else dayspace[setArr[0]][setArr[1]][setArr[s]] = req.body[keyArr[key]]
      }
      if (s == 3) {
        if (setArr.length > s + 1) dayspace[setArr[0]][setArr[1]][setArr[2]][setArr[s]] = {}
        else dayspace[setArr[0]][setArr[1]][setArr[2]][setArr[s]] = req.body[keyArr[key]]
      }
      if (s == 4) dayspace[setArr[0]][setArr[1]][setArr[2]][setArr[3]][setArr[s]] = req.body[keyArr[key]]
    }
  }
  else {
    dayspace[keyArr[key]] = req.body[keyArr[key]]
  }
}

我把鑰匙分開了. 並使用reduce創建除最后一個嵌套值以外的所有值(如果需要),然后將該值分配給在reduce回調中創建或找到的最后一個對象:

 const input = { "bowtime": [ "30", " 1", " 3", " 20" ], "bowstate.levi.leviFlo.totalFloQuot": ".95", "bowstate.crem.cremQuot": "79" }; const output = Object.entries(input).reduce((outerObj, [key, val]) => { if (!key.includes('.')) { outerObj[key] = val; return outerObj; } const keys = key.split('.'); const lastKey = keys.pop(); const lastObj = keys.reduce((a, key) => { // Create an object at this key if it doesn't exist yet: if (!a[key]) { a[key] = {}; } return a[key]; }, outerObj); // We now have a reference to the last object created (or the one that already existed // so, just assign the value: lastObj[lastKey] = val; return outerObj; }, {}); console.log(output); 

我在項目中做過類似的事情。 我已經通過一個名為Flat的流行軟件包實現了它。 鏈接: https//github.com/hughsk/flat

var unflatten = require('flat').unflatten

unflatten({
    'three.levels.deep': 42,
    'three.levels': {
        nested: true
    }
})

// {
//     three: {
//         levels: {
//             deep: 42,
//             nested: true
//         }
//     }
// }

該程序包可以使您的嵌套結構平坦,也可以使嵌套結構扁平化。 還有其他有用的方法。 因此它將更加靈活。

我認為您應該使用它,這將減少項目中的錯誤。

您可以使用較短的方法,即使用一個函數來分割值的路徑並為其生成新的對象。

 function setValue(object, path, value) { var last = path.pop(); path.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value; } var object = { bowtime: ["30", " 1", " 3", " 20" ], "bowstate.levi.leviFlo.totalFloQuot": ".95", "bowstate.crem.cremQuot": "79" }; Object.entries(object).forEach(([key, value]) => { if (!key.includes('.')) return; setValue(object, key.split('.'), value); delete object[key]; }); console.log(object); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

您可以使用Object.entires來獲取對象內的鍵-值對數組,然后使用.split(".").reduce()的對象鍵獲取以將單個對象屬性放入數組中,然后可以使用構建新對象:

 const obj = { "bowtime": [ "30", " 1", " 3", " 20" ], "bowstate.levi.leviFlo.totalFloQuot": ".95", "bowstate.crem.cremQuot": "79" }; const res = Object.entries(obj).reduce((acc, [k, v]) => { const keys = k.split('.'); let cur = acc; keys.length > 1 && keys.forEach(ka => { cur[ka] = cur[ka] || {}; cur = cur[ka]; }); cur[keys.pop()] = v; return acc; }, {}); console.log(res); 

暫無
暫無

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

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