2019屆阿里巴巴模擬題線上程式設計題一
阿新 • • 發佈:2019-01-25
題目
實現一個 css選擇器
示例:
// 參考規則
const rules = {
'a': {
height: 0,
width: 10
},
'#page .content a': {
height: 5
},
'#page a': {
height: 10,
display: 'block'
}
}
// 權重定義,#element(100) > .element(10) > element(1)
const WEIGHT = {
'#': 100 ,
'.': 10,
_default: 1,
}
const getRules = path => {
// your code here
}
console.log(getRules('a'));
//輸出:{height: 0, width: 10}
console.log(getRules('#page a'));
//輸出:{height: 10, width: 10, display: "block"}
console.log(getRules('#page .content a'));
//輸出:{height: 5, width: 10, display: "block"}
分析
在看到題目的時候有點懵逼, 比較混亂不會到從何下手, 所以我提出了一下問題:
- 該rules物件的屬性都是指向的同一個元素嗎?
- 只存在後帶選擇器嗎?
經過反覆思考, 得出一下結論:
應該是指向的同一個元素,
因為: 如果不指向同一個元素, 那麼 #root a 和#page .content a怎麼處理? 這兩個選擇器從可能性上講, 是有可能選中了同一個, 也有可能選中不同客, 那麼具體的返回值是要加上#root a 的值呢還是不加呢? 為了避免出現這樣的歧義, 應該是指向的同一個元素。
只存在後代的關係嗎? 是不是存在>子代的關係呢?
應該是隻存在後代選擇器的, 否則也會出現歧義。
分析到這裡總結下, relus裡面的選擇器都指向同一個元素, 並且只有後代關係, 這種情況下就只需要判斷他們的權值大小, 並且從最小的權值開始新增屬性, 後面的可以覆蓋前面權值較小的屬性的屬性值。 有點繞!!!!需要多理解一下!
我的答案
const getRules = path => {
// your code here
const getWeights = path => {//這是一個獲取選擇器權值的函式
let arr = path.split(' ')
let q = arr.reduce(function (a, b) {
if(b[0] === '#'){
a += 100
}else if (b[0] === '.'){
a += 10
}else {
a += 1
}
return a
}, 0)
return q
}
let weights = getWeights(path)//得到目標選擇器的權值
let arr = []
for(let key of Object.keys(rules)) {//遍歷relus裡的key,得到權值小於等於目標選擇器權值的key
if( weights >= getWeights(key)){
arr.push({key: key, weights: getWeights(key)})
}
}
return arr.sort( (a, b) => a.weights - b.weights).reduce((a, b) => Object.assign(a, rules[b.key]), {})//從小的權值開始向{}上賦值並返回最終的物件
}
結尾
程式碼中使用了sort排序, reduce合併 ,Object.asign淺賦值。如果感覺不好理解需要多補補相關知識。 最後, 如果有錯, 謝謝指正!