1. 程式人生 > >2019屆阿里巴巴模擬題線上程式設計題一

2019屆阿里巴巴模擬題線上程式設計題一

題目

實現一個 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"}

分析

在看到題目的時候有點懵逼, 比較混亂不會到從何下手, 所以我提出了一下問題:

  1. 該rules物件的屬性都是指向的同一個元素嗎?
  2. 只存在後帶選擇器嗎?

經過反覆思考, 得出一下結論:

  1. 應該是指向的同一個元素,

    因為: 如果不指向同一個元素, 那麼 #root  a 和#page .content a怎麼處理?
    這兩個選擇器從可能性上講, 是有可能選中了同一個, 也有可能選中不同客, 那麼具體的返回值是要加上#root a 的值呢還是不加呢? 為了避免出現這樣的歧義, 應該是指向的同一個元素。
    
  2. 只存在後代的關係嗎? 是不是存在>子代的關係呢?

    應該是隻存在後代選擇器的, 否則也會出現歧義。 
    

分析到這裡總結下, 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淺賦值。如果感覺不好理解需要多補補相關知識。 最後, 如果有錯, 謝謝指正!