JS題目之陣列資料拆分重組轉成巢狀物件,讓腦細胞活躍下

CRPER發表於2019-01-17

前言

下班的時候在群裡看到一個小夥伴,在群裡問了一道js的題,發現沒人理會他;

來了興趣就折騰了下,以下是解答過程,用的是ES6+的特性,在chrome跑的;

有興趣的小夥伴可以瞧瞧~~謝謝


題目

JS題目之陣列資料拆分重組轉成巢狀物件,讓腦細胞活躍下

效果圖

JS題目之陣列資料拆分重組轉成巢狀物件,讓腦細胞活躍下

解答

儘量註釋,我分步驟解答

1:陣列變形

格式:先拿到資料格式如下;

[ [ 'code', 'Zh' ],  [ 'code', 'Cn' ],  [ 'taobao', '.cn' ],  [ 'taobao', '.com' ] ]複製程式碼

實現

這一步是拆開資料拿到我們想要的,比如基於大寫字母,基於域名字尾;

因為資料格式是死的,所以正則也相對較為簡單

let arr = ['codeZh', 'codeCn', 'taobao.cn', 'taobao.com'];
let arrSplit = arr.map(item =>
{
if (item.indexOf('.')!== -1){
return item.replace(/(\.)/g, ",$1").split(',')
} else {
return item.replace(/([A-Z])+/g, ",$1").split(',')
}
})console.log(arrSplit);
複製程式碼

2:輸出構建物件資料

格式:先拿到資料格式如下;

[ { 
code: {
Zh: 'codeZh'
}
}, {
code: {
Cn: 'codeCn'
}
}, {
taobao: {
'.cn': 'taobao.cn'
}
}, {
taobao: {
'.com': 'taobao.com'
}
} ]複製程式碼

實現

let arrGroup = arrSplit.map(item =>
{
return {[item[0]]:{[item[1]]:item.join('')
}
}
})console.log(arrGroup);
複製程式碼

3: 實現符合的JSON

格式 : 先拿到資料格式如下;

{ 
"code": {
"Zh": "codeZh", "Cn": "codeCn"
}, "taobao": {
".cn": "taobao.cn", ".com": "taobao.com"
}
}複製程式碼

實現

let resultObj = {
};
for (let i = 0;
i <
arrGroup.length;
i++){
for (const [key, value] of Object.entries(arrGroup[i])) {
resultObj[key] = {
...resultObj[key], ...value
}
}
}console.log(resultObj);
複製程式碼

完整程式碼

// 求陣列轉換成jso//['codeZh', 'codeCn', 'taobao.cn', 'taobao.com'] // 輸出/*{ 
'code':{Zh:'codeZh',Cn:'codeCn'
}, 'taobao':{'.cn':'taobao.cn
},'.com':'taobao.com'
}*/
const resultObj = {
};
let arr = ['codeZh', 'codeCn', 'taobao.cn', 'taobao.com'];
let arrSplit = arr.map(item =>
(item.indexOf('.') !== -1 ? item.replace(/(\.)/g, ",$1").split(',') : item.replace(/([A-Z])+/g, ",$1").split(',')))let arrGroup = arrSplit.map(item =>
({
[item[0]]: {
[item[1]]: item.join('')
}
}))for (let i = 0;
i <
arrGroup.length;
i++){
for (const [key, value] of Object.entries(arrGroup[i])) {
resultObj[key] = {
...resultObj[key], ...value
}
}
}console.log(arrSplit);
console.log(arrGroup);
console.log(resultObj);
複製程式碼

更優雅的姿勢,來自評論

  • 來自掘友Der: 正向預查詢結合reduce組合物件;

程式碼的思路

reducer 主要接受兩個引數,callback(回撥函式)和initialValue(初始值)

回撥函式接收4個引數:(累加器,當前值,當前索引,陣列)

看懂reduce之後就好理解了,傳入空物件作為初始值,正向預查捕獲大寫字母或小數點,

然後以這個為基準點進行切割字串為陣列,提取到兩個變數裡面

依次構建題目所需的格式了,至於最終會輸出一個題目答案的物件,累加器的作用.

傳入值是物件,所以針對遍歷處理的行為都是處理同一個物件

const list = ['codeZh', 'codeCn', 'taobao.cn', 'taobao.com']const result = list.reduce((map, item) =>
{
const [head, tail] = item.split(/(?=[A-Z]|\.)/) map[head] = map[head] || {
} map[head][tail] = item return map
}, {
})console.log(result)複製程式碼

程式碼的思路

這個是replace的高階用法, replace可以傳入正則捕獲,回撥函式包括如下(match,$1,$2),還有偏移量和字串檢測

內部的交換機制和組合與上個法子的差不多

const result = {
} const list = ['codeZh', 'codeCn', 'taobao.cn', 'taobao.com'] list.join().replace(/([a-z]+)([A-Z\.][a-z]+)/g, (m, c0, c1) =>
{
result[c0] = result[c0] || {
} result[c0][c1] = m
}) console.log(result)複製程式碼

總結

這個只是其中的一個解決姿勢,肯定還有其他更優的法子;

僅供參考,不對之處請留言,會及時修正…

來源:https://juejin.im/post/5c4061cb51882525e90ddd65

相關文章