JS直播班 作業檢討--高雄里長OPEN DATA作業

六角學院JS直播班第五周的小組任務,是要撈 《高雄的里長資訊》,我自己做完作業之後,再參考同學寫的code,我認為自己可以再改進優化:

作業要求的任務如下:

  • 里長男女生人數比例
  • 前鎮區有幾個里長
  • 三民區有幾個女性里長
  • 無黨籍、民主進步黨、中國國民黨各佔幾位?
  • 所有區里長人數都整理在一個物件裡

我的高雄市里長資訊作業

資料格式是一個陣列包著物件的JSON檔,物件的屬性為中文命名:

let data = [
    {
    區別: "鹽埕區",
    里別: "藍橋里",
    里長姓名: "陳本興",
    性別: "男",
    生日: "0380817",
    辦公室電話: "075219559",
    住家電話: "075219559",
    手機: "0921236319",
    信箱: "kh01001@kcg.gov.tw",
    辦公室: "鹽埕區藍橋里建國四路344號1樓",
    黨籍: "其他",
    經歷: "改制後第3.4屆,合併後第1.2屆"
    }
    //以下省略
]

以下一一來檢討:

任務一:里長男女生人數比例

我的做法是用陣列的 filter 方法,分別撈出男、女里長的資訊,再來算百分比就好了。

//里長人數等於陣列長度
let villageChiefNum = data.length;

//filter 方法撈出 ["性別"]為男性的里長
let maleNum = data.filter((item) =>{
    return item["性別"] === "男";
})

//filter 方法撈出 ["性別"]為女性的里長
let femaleNum = data.filter((item)=>{
    return item["性別"] === "女";
})

let malePercent = ((maleNum.length/villageChiefNum)*100).toFixed(2);
let femalePercent =((femaleNum.length/villageChiefNum)*100).toFixed(2);
console.log(`高雄市的男性里長有 ${maleNum.length} 位,佔所有里長 ${malePercent} %的比例;
女性里長有 ${femaleNum.length} 位,佔所有里長 ${femalePercent} %的比例`)

//高雄市的男性里長有 704 位,佔所有里長 79.01 %的比例;
//女性里長有 187 位,佔所有里長 20.99 %的比例

而同學的做法如下:

const genderRatioCalc = () => {
    //設定初始值  
    let maleNum = 0;
    let femaleNum = 0;
    //用if else來處理男女人數
    data.forEach((item) => {
        if (item['性別'] === '男') {
            maleNum += 1;
        } else {
            femaleNum += 1;
        }
    })
    let malePercent = ((maleNum / villageChiefNum) * 100).toFixed(2);
    let femalePercent = ((femaleNum / villageChiefNum) * 100).toFixed(2);
    console.log(`高雄市的男性里長有 ${maleNum} 位,佔所有里長 ${malePercent} %的比例;
    女性里長有 ${femaleNum} 位,佔所有里長 ${femalePercent} %的比例`)
}
genderRatioCalc();

任務一檢討:

  • 我沒有先用 if else 去想,而事先想用 filter 撈出陣列,跳過邏輯判斷的部分。
  • 沒用 input output 的觀念來思考,以至於忽略了可以封裝成一個函式。

任務二:前鎮區有幾個里長

我這樣做:

let villageArr = data.filter((item) => item["區別"] === "前鎮區");
console.log(`前鎮區里長有${villageArr.length}`);

任務三: 三民區有幾個女性里長

我這樣做:

let sanminDistrictFemale = data.filter((item) => {
    return (item["區別"] === "三民區" && item["性別"] === "女");
})
console.log(`三民區女性區長有${sanminDistrictFemale.length}`);

同學把任務二跟三包裝成一個函式來處理:

function villageChief(villageName, sex = '') {
    //設一個空陣列
    let villageArr = [];
    //如果性別為空字串(沒有查詢),只要處理 里長的人數
    if (sex === '') {
        villageArr = data.filter((item) => item['區別'] === villageName);
        console.log(villageArr);
        console.log(`${villageName}里長有${villageArr.length}`);
    } else {
        //否則 里長的人數 與 性別都做處理
        villageArr = data.filter((item) => item["區別"] === villageName && item["性別"] === sex)
        console.log(`${villageName}${villageArr.length}${sex}里長`);
    }
}
villageChief('前鎮區');
villageChief('三民區','女');

任務二、三檢討:

  • 沒用 input output 的觀念來思考。
  • 根本沒想到 兩個任務可以合併來寫。
  • 忽略了參數屬值的設定( sex === ‘’ ),可以拿來做 if else 判斷,這個要學起來。

任務四:無黨籍、民主進步黨、中國國民黨各佔幾位?

因為有指定黨籍,所以我這麼做:

let party = {
    "國民黨": 0,
    "民主進步黨": 0,
    "中國國民黨": 0
};
data.forEach(function (item) {
    party[item["黨籍"]] += 1
})
console.log(`高雄無黨籍有${party["無黨籍"]}`);
console.log(`高雄民主進步黨有${party["民主進步黨"]}`);
console.log(`高雄中國國民黨有${party["中國國民黨"]}`);

但是同學這樣做:

const partChiefCount = (party) => {
    let partyChiefNum = 0;
    data.forEach((item) => {
      if (item['黨籍'] === party) partyChiefNum += 1;
    });
    console.log(`${party}共有${partyChiefNum}位里長`);
  }
  partChiefCount('無黨籍');
  partChiefCount('民主進步黨');
  partChiefCount('中國國民黨');
  • 一樣是忽略了 input 與 output。
  • 如果今天不是指定要那些黨,我就要改變做法了。

任務五:所有區里長人數都整理在一個物件裡

作業要求最後輸出時要變成以下的樣子:

let total = {
    "前鎮區":30,
    "三民區":50,
    "苓雅區":79,
}

我的想法:

  1. 撈出資料中所有的區,把它放入一個空陣列中。
  2. 過濾掉重複的區 ,變成一個新的陣列 distArry
  3. 把各區的名字變成物件 distObj 的屬性
  4. 把data的區別屬性,與distObj的區別屬性比對,兩者相同就加一
    //撈出資料中所有的區,放入一個空陣列中:
    let dist = [];
    data.forEach(function (item) {
        distName = item["區別"];
        dist.push(distName);
    })
    
    
    //過濾掉重複的區
    let distArry = dist.filter(function (item, index) {
        return dist.indexOf(item) === index;
    })
    
    
    //把所有的區名變成物件屬性,預設值為 0
    let distObj = {};
    distArry.map(function (item, index) {
        distObj[item] = 0;
    })
    
    //跑data陣列物件與distObj物件比對,區別的值與物件的屬性一樣,那物件那邊的屬性值就加一
    //三角關係:data,distArry,distObj
    data.forEach(function (item, index, array) {
        distObj[item['區別']] += 1;
    })

同學的做法,又快又簡單:

let total = {};
const organizeChiefOfVillage = () => {
    data.forEach((item) => {
        //如果物件沒有該屬性的話,則設置屬性,並給初始值數值 1
        if (total[item['區別']] === undefined) {
            total[item['區別']] = 1;
        } else {
        // 如果物件有屬性,則直接+1
            total[item['區別']] += 1;
        }
    });
}
organizeChiefOfVillage();
console.log(total);

任務五檢討

可能是剛做完陣列方法的筆記,對於 filter 的印象太過深刻,所以思考路徑會一直往 filter 跑,完全忘記用 if else 也可以篩選,還有是物件取值的方法不夠熟練,所以不會往那邊去想解決方法。

最後要做的時候要想 input 與 output,盡量想想怎樣可以更完整的解決問題。


JS直播班 作業檢討--高雄里長OPEN DATA作業
https://popeye-ux.github.io/2021/11/25/villageOpenData/
作者
POPEYE
發布於
2021年11月25日
許可協議