這篇是為了紀錄 Lidemy 程式導師實驗計畫第五期的期中考 我想好久還是沒過關的題目
原始資料:
[
{author:aaa, bookTitle:'bookA'},
{author:bbb, bookTitle:'bookB'},
{author:aaa, bookTItle:'bookC'},
{author:aaa, bookTitle:'bookD'},
{author:bbb, bookTitle:'bookE'},
{author:ccc, bookTitle:'bookF'},
]
將原始資料,改成這樣 :
[
{author:aaa, bookTitle:['bookA', 'bookC', 'bookD']},
{author:bbb, bookTitle:'bookB', 'bookE'},
{author:ccc, bookTitle:'bookF'}
]
- 將一樣 author 的 bookTitle 整理成陣列
- 要確定作者出現的順序與bookTitle順序要跟原始資料一樣
1)
const data = [
{author:'aaa', bookTitle:'bookA'},
{author:'bbb', bookTitle:'bookB'},
{author:'aaa', bookTitle:'bookC'},
{author:'aaa', bookTitle:'bookD'},
{author:'bbb', bookTitle:'bookE'},
{author:'ccc', bookTitle:'bookF'},
]
const result = []
const uniqueAuthor = []
for(let i =0 ; i < data.length; i++){
if(!uniqueAuthor.some(x => x=== data[i].author)){
uniqueAuthor.push(data[i].author)
}
}
for(let i =0; i< uniqueAuthor.length;i++){
let authorArr = data.filter(el => el.author === uniqueAuthor[i])
let titleArr = authorArr.map(el=> el.bookTitle)
result.push({
author:uniqueAuthor[i],
bookTitle:titleArr.length >1 ? titleArr:titleArr[0]
})
}
console.log(result)
先解釋這段
const uniqueAuthor = []
for(let i =0 ; i < data.length; i++){
if(!uniqueAuthor.some(x => x=== data[i].author)){
uniqueAuthor.push(data[i].author)
}
}
這段是利用 some
(some 為陣列中是否至少有一個元素) ,將 author 整理成陣列放入uniqueAuthor
,讓 author 沒有重複
這邊其實也可以利用 Set 或者其他 method 改寫,( 功力太弱,一開始都把題目想得很複雜,自以為很帥的想一堆 method 來解決問題! )
總之,第一步一定要先解決 author 重複的狀況,所以想辦法把 author 改成都沒有重複的形式,就好解決了。
例如利用 Set :
const uniqueAuthor = [...new Set(data.map(book => book.author))]
再來解釋這段
for(let i =0; i< uniqueAuthor.length;i++){
let authorArr = data.filter(el => el.author === uniqueAuthor[i])
let titleArr = authorArr.map(el=> el.bookTitle)
result.push({
author:uniqueAuthor[i],
bookTitle:titleArr.length >1 ? titleArr:titleArr[0]
})
}
先利用 filter
將一樣 author 的資料整理成陣列放到 author 中。
這時候去 console 的話會得到這樣的結果
[
{ author: 'aaa', bookTitle: 'bookA' },
{ author: 'aaa', bookTitle: 'bookC' },
{ author: 'aaa', bookTitle: 'bookD' }
]
[
{ author: 'bbb', bookTitle: 'bookB' },
{ author: 'bbb', bookTitle: 'bookE' }
]
[ { author: 'ccc', bookTitle: 'bookF' } ]
接著再將 bookTitle 整理成陣列,讓 titleArr 變成這樣
[ 'bookA', 'bookC', 'bookD' ]
[ 'bookB', 'bookE' ]
[ 'bookF' ]
確定這兩個步驟都 OK , 然後再將它們組合起來 push 到 result
result.push({
author:uniqueAuthor[i],
bookTitle:titleArr.length >1 ? titleArr:titleArr[0]
})
解決這題目的方式其實很多種,在這邊我只列出我實際練習過的形式出來,但是思路上其實都大同小異,最難的還是再怎麼將心中的步驟用程式去實現出來。
後來老師有提供解答,我覺得很適合讓我清楚整個解題的邏輯,在這邊列出老師提供的解決方式 :
2)
let result = []
for(let i = 0; i < data.length; i++){
const currentData = data[i]
const index = result.findIndex(book => book.author === currentData.author)
if(index >= 0){
if(!Array.isArray(result[index].bookTitle)){
result[index].bookTitle = [result[index].bookTitle]
}
result[index].bookTitle.push(currentData.bookTitle)
} else {
result.push(currentData)
}
}
console.log(result)
首先是利用 findIndex
找尋 result 陣列中與currentData 一樣 author 的 index ,如果沒找到會回傳 -1。
如果回傳 -1 ,會將 currentData 新增到 result 中。
假設有找到,就會先確定此時 result 中的 bookTitle 是不是陣列,如果不是就轉換成陣列,然後將新的 bookTitle 新增到到這陣列中。
如果覺得解釋得不夠清楚的話,可以建議每個步驟都去 console 出來,應該就會比較清楚每一步驟在幹什麼,這部分真的不是很好懂。
也謝謝老師提供了這個題目讓我清楚我哪邊需要再加強,還有其實好多同學都有不一樣的解法(覺得厲害👍🏽 ),每個人思考方式不一樣,這是一定的,怎麼實現、怎麼正確的呈現才是重要的。