[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 : ดีงข้อมูลออก จาก Object ที่ลึกๆ มาจัดแถว
const _ = require('lodash');

const users = [
  { name: 'Alice', pets: ['cat', 'dog'] },
  { name: 'Bob', pets: ['parrot'] }
];

const allPets = _.flatMap(users, user => user.pets);
console.log(allPets); // Output: ['cat', 'dog', 'parrot']
  • 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.