[JS] ใช้ Library lodash จัดการกับข้อมูล

ช่วงนี้ผมได้ไปเรียน Course Online ที่จัดโดยสมาคมโปรแกรมเมอร์ไทยครับ เกี่ยวกับ JS+Angular+FireBase ครับ โดยระหว่างเรียนมีการบ้านให้จำนวน 4 ข้อ ก่อนจะไปลองโจทย์ มารู้วิธีการเล่นกับข้อมูลก่อน (Data Model) ว่าตัว Java Script มี function อะไรให้ใช้งานบ้างครับ

  • map : จัดการกับข้อมูลแต่ละตัว ด้วยการทำงานที่เหมือนกัน เช่น ยกกำลังในตัวเลขทุกๆตัว ใน Array ครับ โดยผมมีตัวอย่างที่ใช้ for กับ map ครับ
    const arr = [1,2,3,4,5,6]
    
    const arr2 = []
    for(let i = 0; i < arr.length; ++i){ arr2.push(arr[i] * arr[i]) } console.log('Source Data') console.log(arr) console.log('Array Pow with loop') console.log(arr2) /* Source Data [ 1 , 2, 3 , 4, 5 , 6] Array Pow with loop [ 1, 4, 9, 16, 25, 36 ] */ const power2 = (x) => x * x
    const arr3 = arr.map((x) => x * x)
    //const arr3 = arr.map(power2)
    console.log('Source Data')
    console.log(arr)
    console.log('Array Pow with map')
    console.log(arr3)
    /*
    Source Data
    [ 1, 2, 3, 4, 5, 6 ]
    Array Pow with map
    [ 1, 4, 9, 16, 25, 36 ]
    */
    
  • flatmap :
  • filter : กรองข้อมูลตามเงื่อนไข คล้ายกับ Where ใน SQL
    const arr = [1,2,3,4,5,6]
    
    const arr2 = arr.filter((x) => x % 2 === 0)
    
    console.log('Source Data')
    console.log(arr)
    console.log('Filter Array')
    console.log(arr2)
    
    /*
    Source Data
    [ 1, 2, 3, 4, 5, 6 ]
    Filter Array
    [ 2, 4, 6 ]
    */
    
  • reduce : เอาข้อมูลทุกตัวใน Array มาทำอะไรที่ต่อเนื่องกัน ให้ได้ผลลัพธ์ออกมาครับ ตัวอย่างเป็นการ หาผลคูณของตัวเลขทุกๆตัวใน Array ครับ อ๋อ reduce แบบ 2 แบบนะครับ เริ่มทำจากทางซ้าย(reduce) หรือ เริ่มจากทางขวา(reduceRight)
    const arr = [1,2,3,4,5,6]
    /*
        reduce ได้ผลลัพธ์ค่าเดียว 
        (ค่่าก่อนหน้า previous, ค่าปัจจุุบัน current) => เอาไปทำอะไร, เริ่มต้นจาก 
    
        1 * 1 = 1
        1 * 2 = 2
        2 * 3 = 6
        6 * 4 = 24
        24 * 5 = 120
        120 * 6 = 720
    */
    
    const arr2 = arr.reduce((p, c) => p * c, 1)
    
    console.log('Source Data')
    console.log(arr)
    console.log('reduce')
    console.log(arr2)
    /*
    Source Data
    [ 1, 2, 3, 4, 5, 6 ]
    Array Reduce
    720
    */
    
    const arr3 = arr.reduceRight((p, c) => p * c, 1)
    console.log('Source Data')
    console.log(arr)
    console.log('reduceRight')
    console.log(arr3)
    
  • every : ตรวจข้อมูลทุกตัวใน Array ว่าตรงตามเงื่อนไข หรือไม่ ตัวอย่าง Code เป็นการตรวจสอบตัวเลขทุกตัวใน Array ว่าเป็นเลขคู่ หรือไม่ โดยการทดสอบ mod 2 ต้องได้ 0
    const arr = [1,2,3,4,5,6]
    
    /*
        ตรวจทุก Element ใน Array ทุกตัว ว่าตรงตามเงื่อนไขไหม
    */
    const arr2 = arr.every((x) => x % 2 === 0)
    
    console.log('Source Data')
    console.log(arr)
    console.log('every Array')
    console.log(arr2)
    
    /*
    Source Data
    [ 1, 2, 3, 4, 5, 6 ]
    Filter Array
    false
    */
    
  • some : ตรงข้ามกับ every ครับ โดยดูว่ามีข้อมูลบางตัวตรวจตามเงื่อนไข หรือไม่ครับ ตัวอย่างที่ผมทำเป็นการตรวจสอบตัวเลขบางตัวใน Array ว่าเป็นเลขคู่ หรือไม่
    const arr = [1,2,3,4,5,6]
    
    /*
        ตรวจว่ามีบาง Element ใน Array ทุกตัว ว่าตรงตามเงื่อนไขไหม
    */
    const arr2 = arr.some((x) => x % 2 === 0)
    
    console.log('Source Data')
    console.log(arr)
    console.log('some Array')
    console.log(arr2)
    
    /*
    Source Data
    [ 1, 2, 3, 4, 5, 6 ]
    Filter Array
    true
    */
    

ตัวโจทย์ตั้ง 4 ข้อ ผมใช้ตัว Lodash (ผมมองว่ามันเป็น Super Util Library) ลองเล่นกับข้อมูลที่ผู้สอนเตรียมไว้ ดังนี้ครับ

  • นักร้อง แต่ละคนร้องเพลงเฉลี่ย กี่วินาที
    const library = require('./library')
    const _ = require('lodash')
    const result = _(library)
        .groupBy('Artist')
        .map((tracks, Artist) =>{
            return {
                Artist,
                avg: _(tracks).map((track) => track['Total Time']).mean()
            }
        })
        .value()
    
    console.log(result)
    
  • นักร้อง แต่ละคน เริ่มร้องเพลงปีไหน
    const library = require('./library')
    const _ = require('lodash')
    const result = _(library)
        .groupBy('Artist')
        .map((tracks, Artist) =>{
            return {
                Artist,
                startdate: _(tracks).map((track) => track.Year).min()
            }
        })
        .value()
    console.log(result)
    
  • Genre เพลงแต่ละประเภทมีกี่เพลง
    const library = require('./library')
    const _ = require('lodash')
    const result = _(library)
        .groupBy('Genre')
        .map((tracks, Genre) =>{
            return {
                Genre,
                CountTrack: _(tracks).map((track) => track.Name).uniq().value().length
            }
        })
        .value()
    console.log(result)
    
  • จัดรูปแบบตามนี้ ที่กำหนดครับ
    [
    	{
    		Album: 'aaa'
            Tracks: ['','',''],
            Artists: ['','','']
    	}
    ]
    

    เขียน Code ได้ผลลัพธ์ ดังนี้

    const library = require('./library')
    const _ = require('lodash')
    const tranfromResult = _(library).groupBy((track) => track.Album)
                                     .map((tracks, name) => {
                                         return {
                                             Album: name, 
                                             Tracks : _(tracks).map((track) => track.Name)
                                                               .uniq()
                                                               .value(),
                                             Artist : _(tracks).map((track) => track.Artist)
                                                               .uniq()
                                                               .value()
                                         }
                                     })
                                     .value()
    console.log(tranfromResult)
    

หลังจากได้เรียน Section นี้ไป ถ้ามีพื้นฐานอย่างตัว SQL ช่วงทำให้เข้าใจข้อมูลได้ง่าย และถ้ารู้เรื่องพวก Functional Programming อย่างของผมที่หลักๆ ใช้ C# พวก Linq กับ Lambda Expression จะช่วยให้ไปได้ไวขึ้นครับ อ๋อแล้วก็ Code ผมพยายามเอาขึ้น GitHub นะครับ


Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts sent to your email.