前言
下班的時候在群裡看到一個小夥伴,在群裡問了一道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)
複製程式碼
總結
這個只是其中的一個解決姿勢,肯定還有其他更優的法子;
僅供參考,不對之處請留言,會及時修正...