2017-08-05 118 views
0

我正在使用無法在服務器端修改的數據集。所以我試圖在客戶端設置本地數據模型,以便在更新部分數據時輕鬆遍歷模型。使用Immutable.js從嵌套列表創建鍵控映射

因此,我試圖從多級地圖(包括列表)創建多級地圖,這些地圖包括地圖等(請參閱本文末尾的示意圖)。

我想要得到的是包含其他地圖的地圖,其中包含的地圖的關鍵是對象的值(請參閱本文末尾的示意圖)。

我得到它的第一級工作:

const firstLevel = data.toMap().mapKeys((key, value) => value.get('value')); 

看到它在這裏的行動:https://jsfiddle.net/9f0djcb0/4/

但有一個最大的3級嵌套數據的是,我不能讓我的回頭看看如何完成轉換。任何幫助感謝!

示意圖數據集:

// This is what I got 
const dataset = [ 
    { 
    field: 'lorem', 
    value: 'ipsum', 
    more: [ 
     { 
     field: 'lorem_lvl1', 
     value: 'ispum_lvl1', 
     more: [ 
      { 
      field: 'lorem_lvl2', 
      value: 'ispum_lvl2', 
      more: [ 
       { 
       field: 'lorem_lvl3', 
       value: 'ispum_lvl3', 
       } 
      ] 
      } 
     ] 
     } 
    ] 
    }, 
    { 
    field: 'glorem', 
    value: 'blipsum' 
    }, 
    { 
    field: 'halorem', 
    value: 'halipsum' 
    } 
]; 

這就是我想去的地方:

// This is what I want 
const dataset_wanted = { 
    ipsum: { 
    field: 'lorem', 
    value: 'ipsum', 
    more: { 
     lorem_lvl1: { 
     field: 'lorem_lvl1', 
     value: 'ispum_lvl1', 
     more: { 
      lorem_lvl2: { 
      field: 'lorem_lvl2', 
      value: 'ispum_lvl2', 
      more: { 
       lorem_lvl3: { 
       field: 'lorem_lvl3', 
       value: 'ispum_lvl3', 
       } 
      } 
      } 
     } 
     } 
    } 
    }, 
    glorem: { 
    field: 'glorem', 
    value: 'blipsum' 
    }, 
    halorem: { 
    field: 'halorem', 
    value: 'halipsum' 
    } 
}; 

回答

0

至於更生成的解決方案,我重新寫的答案之前,遞歸方法:

function mapDeep(firstLevel) { 
    return firstLevel.map((obj) => { 
    if (obj.has('more')) { 
     const sec = obj.get('more').toMap().mapKeys((key, value) => value.get('value')); 
     const objNext = mapDeep(sec); 
     obj = obj.set('more', objNext); 
    } 
    return obj; 
    }); 
} 

第一個層面仍然需要手動之前被映射。

const firstLevel = data.toMap().mapKeys((key, value) => value.get('value')); 
const secondLevel = mapDeep(firstLevel); 

再次看到它在行動:https://jsfiddle.net/9f0djcb0/12/

這是不夠好,我現在。仍然覺得這可以解決更聰明(和更高性能)..乾杯:)

0

檢索嵌套結構使用 「getIn」 是尤爲明顯。

const data = Immutable.fromJS(dataset[0]); 
const firstLevel = data.getIn(['more']); 
const twoLevel = firstLevel.getIn([0,'more']); 
const threeLevel = twoLevel.getIn([0,'more']); 
console.log(firstLevel.toJS(),twoLevel.toJS(),threeLevel.toJS()); 
+0

嗨@Coder,感謝您的快速回答。 我知道按需檢索嵌套數據的想法。但是我試圖實現的不僅僅是「讀取」嵌套結構,而是將它從示例A(//這是我得到的)轉換爲示例B(//這是我想要的)。 我不太清楚getIn()的幫助。你能解釋一下更深一點嗎? – derdaani

0

所以經過一些時間的推移,我想出了爲我工作的解決方案:

let sec, third, objThird; 

// 1st level: simple mapping 
const firstLevel = data.toMap().mapKeys((key, value) => value.get('value')); 

// 2nd level: walk through updated firstLevel's subobjects and do the mapping again: 
const secondLevel = firstLevel.map((obj) => { 
    if (obj.has('more')) { 
    sec = obj.get('more').toMap().mapKeys((key, value) => value.get('value')); 

    // 3nd level: walk through updated secondLevel's subobjects and do the mapping again: 
    objThird = sec.map((o) => { 
     if (o.has('more')) { 
     third = o.get('more').toMap().mapKeys((key, value) => value.get('value')); 
     o = o.set('more', third); 
     } 
     return o; 
    }); 
    obj = obj.set('more', objThird); 
    } 
    return obj; 
}); 

看到它在這裏的行動:https://jsfiddle.net/9f0djcb0/7/

這一直很好,到目前爲止,週四相當硬編碼。如果有人有一個更優雅的解決方案,我很高興瞭解它!