iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 21
0

今日kata

原始題目如下:(6kyu)
The new "Avengers" movie has just been released! There are a lot of people at the cinema box office standing in a huge line. Each of them has a single 100, 50 or 25 dollar bill. An "Avengers" ticket costs 25 dollars.
Vasya is currently working as a clerk. He wants to sell a ticket to every single person in this line.
Can Vasya sell a ticket to every person and give change if he initially has no money and sells the tickets strictly in the order people queue?
Return YES, if Vasya can sell a ticket to every person and give change with the bills he has at hand at that moment. Otherwise return NO.

翻譯:
電影院售票,每張票價$25,顧客會持$25 $50 $100不同面額來買票,售票人員需判斷是否有足夠零錢可找給顧客。

範例:

tickets([25, 25, 50]) // => YES 
tickets([25, 100]) // => NO. Vasya will not have enough money to give change to 100 dollars
tickets([25, 25, 50, 50, 100]) // => NO. Vasya will not have the right bills to give 75 dollars of change (you can't make two bills of 25 from one of 50)

構想&解法

function tickets(peopleInLine) {
 let change={
   '25':0,
   '50':0
 }
 
 for(let i=0;i<peopleInLine.length;i++){
   switch (peopleInLine[i]){
       case 25:
       change['25']++
       break;
       case 50:
       if (change['25']!==0){
         change['25']--
         change['50']++
         }else{
           return 'NO'
         }
       break;
       case 100:
      if(change['25']>=1&& change['50']>=1){
         change['25']--
         change['50']--
       }else if(change['25']>=3){
         change['25']-=3
       }else {
         return 'NO'
       }
       break;
   }
 }
 return 'YES'
}

判斷是否有足夠零錢可以找給顧客,宣告一change物件負責記錄$25和$50的數量。一一遍歷買票的人潮:

  • $25: 不用找零,change['25']+1
  • $50:找$25,change['25']-1,change['50']+1
  • $100:找$75
    • 找一張$25 & 一張$50,change['25']-1,change['50']-1
    • 找三張$25,change['25']-3

其他解法觀摩

function tickets(peopleInLine){
  let [c25,c50,c100] = [0,0,0];
  for(let v of peopleInLine) {
    if(v===25) c25++;
    if(v===50) {c50++; c25--;}
    if(v===100) {c25--; c50>0?c50--:c25-=2;}
    if(c25<0||c50<0) return 'NO'
  }
  return 'YES'
}

switch case改成以四項if判斷,簡潔好多!!
遇到拿$100結帳的顧客,一律先將coin 25數量減一;再由coin 50的數量是否大於0,決定要減一張$50還是$25。最後檢查coin數量是否小於0。


整理用法

解構賦值(Destructuring assignment)

最常用在把陣列或物件中的資料擷取出來成獨立的變數。 以下整理陣列解構的用法或時機!

陣列解構

// 陣列儲存姓和名
let arr = ["Waa","Wei"]

// 解構賦值
// set firstName= arr[0] and lastName= arr[0]
let [firstName,lastName]=arr

console.log(firstName) // Waa
console.log(lastName)  // Wei

  • 可以跟其他會回傳陣列的Methods結合 (Ex:split())
let [firstName,lastName]='Waa Wei'.split(' ')

很有感/images/emoticon/emoticon02.gif


  • 解構不代表破壞,destructuring代表複製item(記憶體位址)給變數,但陣列本身不會被改變
// 語法 let [a,b]=arr 可以寫成下面兩行
 let a = arr[0]
 let b = arr[1]
// arr沒有被異動

  • 陣列中不想要的元素可以使用逗號跳過。
// 跳過第二個元素
let [firstName, , title]=['Waa','Wei','OhYa DJ','31-GMA']
console.log(title) // OhYa DJ

其中第二個元素Wei被跳過沒被指派給任何變數,第三個元素OhYa DJ被指派給title,陣列剩餘的元素沒有對應的變數也一樣被跳過。


  • 等號右側除了放陣列,其他任何可迭代的都可以。
let [a, b, c] = "abc"; // ["a", "b", "c"]
let [one, two, three] = new Set([1, 2, 3]);

解構賦值是一一取出位置0,1,2,3的值,Ex:字串可以使用index來取出字元。'abc'[0]為a。所以並不限於陣列!


  • 左側可以任意指派,例如指派給物件的屬性
let user = {};
[user.name, user.surname] = "Waa Wei".split(' ');

console.log(user.name); // Waa

  • 迴圈中搭配使用entries(),將物件的key和value一一解構賦值。
let user = {
  name: "Waa",
  age: 30
};

// loop over keys-and-values
for (let [key, value] of Object.entries(user)) {
  alert(`${key}:${value}`); // name:Waa, then age:30
}

  • 變數互換
let guest = "Waa";
let admin = "Lulu";

// Swap values: make guest=Lulu, admin=Waa
[guest, admin] = [admin, guest];

alert(`${guest} ${admin}`); // Lulu Waa 

  • 如果想要把剩下未被指派給變數的元素給集合起來,可以使用...(the rest)
let [name1, name2, ...rest] = ["Waa", "Rockmui", "DJ", "HitFM"];

alert(name1); // Waa
alert(name2); // Rockmui

// 提醒 rest是陣列 (rest為陣列名稱可自訂)
alert(rest[0]); // DJ
alert(rest[1]); // HitFM
alert(rest.length); // 2

  • 避免出現undefined或是一些不必要的錯誤產生,有時候需要給變數預設值
// default values
let [name = "Guest", surname = "Anonymous"] = ["Waa"];

alert(name);    // Waa (from array)
alert(surname); // Anonymous (default used)
  • 預設值也可以call function來取得,例如利用prompt function,來提醒輸入未被指派的surname
// runs only prompt for surname
let [name = prompt('name?'), surname = prompt('surname?')] = ["shan"];

alert(name);    // shan (from array)
alert(surname); // whatever prompt gets

又來一個期待
期待後面有篇幅再繼續整理Object destructuring Nested destructuring 更多解構的用法/images/emoticon/emoticon02.gif

以上內容參考自
MDN web docs-Destructuring assignment
Javascript.info-Destructuring assignment

以上為今日分享的內容,若有錯誤或是建議,請再隨時和我聯繫。


上一篇
Valid Braces
下一篇
Directions Reduction
系列文
菜鳥工程師的奇幻漂流:跟著kata活化手指和意識30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言