前言
下班的時候在群裡看到一個小夥伴,在群裡問了一道js
的題,發現沒人理會他;
來了興趣就折騰了下,以下是解答過程,用的是ES6+
的特性,在chrome跑的
;
有興趣的小夥伴可以瞧瞧~~謝謝
題目
效果圖
解答
儘量註釋,我分步驟解答
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)複製程式碼
總結
這個只是其中的一個解決姿勢,肯定還有其他更優的法子;
僅供參考,不對之處請留言,會及時修正…