Slide 1

Slide 1 text

SELECT keyName, valueArray(keyName, array) FROM array GROUP BY keyName Array Grouping will soon be KansaiTS#5 @jiko21 arriving at TypeScript

Slide 2

Slide 2 text

About jiko21… Name: Daiki Kojima (jiko21) Multistack Engineer @ AppBrew.inc Love: Guitar, TypeScript, baseball @jiko21 @jiko_21

Slide 3

Slide 3 text

Array grouping

Slide 4

Slide 4 text

About array grouping method • ڈ೥ʹͳͬͯECMAScriptʹೖͬͨproposal • Α͏΍͘TypeScript 5.4Ͱܕ৘ใ͕௥Ճ͞ΕΔʂ • ରԠ͞ΕͯΔϒϥ΢β͸͔ͳΓݶఆత https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/groupBy

Slide 5

Slide 5 text

About array grouping method • ഑ྻ಺ཁૉΛgroupԽͨ͠object(Object.groupBy)΍ map(Map.groupBy)͕ੜ੒Ͱ͖Δ • SQLͰ͍͏GroupByͬΆ͍ (sumͱ͔count͕Ͱͯ͘ΔΘ͚Ͱ͸ͳ͍͕) const array = [1, 2, 3, 4, 5]; const groupByResult = Object.groupBy(array, (nu m ) => { return num % 2 === 0 ? 'even': 'odd'; }); /** * { * 'even': [2, 4], * 'odd': [1, 3, 5], * } */ console.log(groupByResult)

Slide 6

Slide 6 text

ࠓ·Ͱͩͱ… const array = [1, 2, 3, 4, 5]; const result = { even: [] as number[], odd: [] as number[], }; array.forEach((value) => { if (value % 2 === 0 ) { result.even.push(value) } else { result.odd.push(value) } }); GPS&BDIͰճͯͦ͠ΕͧΕཁૉΛQVTI

Slide 7

Slide 7 text

ࠓ·Ͱͩͱ… const array = [1, 2, 3, 4, 5]; const result = array.reduce((prevValue, currentValue) => { if (currentValue % 2 === 0 ) { prevValue.even.push(currentValue) } else { prevValue.odd.push(currentValue) } return prevValue; }, { even: [] as number[], odd: [] as number[], }); "SSBZSFEVDFͰແཧ΍Γ͓͠ΌΕʹ

Slide 8

Slide 8 text

ͳΜͰstatic methodͳͷ͔ʁ • ౰ॳ͸Array.prototype.groupByΛߟ͍͕͑ͯͨ͢Ͱʹsugar ͱ͍͏ϥΠϒϥϦ͕groupByΛmonkey patchͰ౰ͯͯͨ • Array.prototype.group΋ߟ͕͑ͨ഑ྻΛHashMapʹ͢Δίʔυɹ ʹͿ͔ͭΔͷͰ݁ہstatic methodʹ • https://github.com/tc39/proposal-array-grouping/ ʹ΋ৄࡉ͕ࡌ ͬͯ·͢

Slide 9

Slide 9 text

࢖͍ॴ

Slide 10

Slide 10 text

͜͏͍͏σʔλΛද͍ࣔͨ͠… const todos = [ { status: 'TODO', text: 'إΛચ͏', }, { status: 'TODO', text: 'ࣃΛຏ͘', }, { status: 'DOING', text: '෩࿊ʹೖΔ', }, { status: 'DONE', text: 'ञΛҿΉ', }, ];

Slide 11

Slide 11 text

݁ߏ؆୯ʹॻ͚·͢! function App() { const groupedTodos: { 'TODO': Todo[]; 'DOING': Todo[]; 'DONE': Todo[]; } = Object.groupBy(todos, (ite m ) => { return ite m .status; }); return (
ite m .text)} /> ite m .text)} /> ite m .text)} />
) } 'JMUFS஍ࠈ͔Βൈ͚ग़ͤΔʂ

Slide 12

Slide 12 text

ύϑΥʔϚϯε

Slide 13

Slide 13 text

ύϑΥʔϚϯε • ৽͍͠method͕ੜ͑ͯɺܕ৘ใ΋௥Ճ͞Εͨͱ͍͏͜ͱ͸ɺɹɹɹ ͦΕ૬Ԡʹ͍͍…͸ͣʂ • ύϑΥʔϚϯεʹ໰୊͕͋Δͱ৽͍͠ϝιου͕͋ͬͯ΋࢖͏ͷ͕ɹ ͨΊΒΘΕΔ…

Slide 14

Slide 14 text

࣮ݧͯ͠ΈΔ • 0, 1, …, N-1͕ೖͬͨ഑ྻ͔ΒҎԼͷΑ͏ͳobjectΛੜ੒͢Δ • ࣮ߦ؀ڥ • bun: v1.0.25 • ϚγϯεϖοΫ: Apple M1 Pro / 32GB { even: [ 0 , 2, ...], odd: [1, 3, ...] }

Slide 15

Slide 15 text

Object.groupBy͸͜ΕͰൺֱ inputArray.reduce((prevValue, currentValue) => { if (currentValue % 2 === 0 ) { prevValue.even.push(currentValue) } else { prevValue.odd.push(currentValue) } return prevValue; }, { even: [] as number[], odd: [] as number[], }) Object.groupBy(inputArray, (nu m ) => { return num % 2 === 0 ? "even": "odd"; }) WT

Slide 16

Slide 16 text

ύϑΥʔϚϯε ͳΜ͔શൠతʹॏ͍ʜ

Slide 17

Slide 17 text

Map.groupBy͸͜ΕͰൺֱ const map = new Map(); const evenArray: number[] = []; const oddArray: number[] = []; inputArray.forEach((currentValue) => { if (currentValue % 2 === 0 ) { evenArray.push(currentValue); } else { oddArray.push(currentValue); } }); map.set('even', evenArray); map.set('odd', oddArray); Map.groupBy(inputArray, (nu m ) => { return num % 2 === 0 ? "even": "odd"; }) WT

Slide 18

Slide 18 text

ύϑΥʔϚϯε ͋Μ·Γ͕ࠩͳ͍

Slide 19

Slide 19 text

͋ΕΕɺɺɺ

Slide 20

Slide 20 text

݁Ռ͸ඍົ • Map.groupBy͸ͦΜͳʹେࠩͳ͠… • Object.groupBy͚ͩ࿐ࠎʹ஗͘ͳͬͯͦ͏…

Slide 21

Slide 21 text

TC39 Array GroupingΛಡΜͰΈΔ… https://tc39.es/proposal-array-grouping/

Slide 22

Slide 22 text

ٖࣅίʔυΛॻ͍ͯΈΔͱ… function Object.groupBy(array, callback) { groups = GroupBy(array, callback, property); obj = {}; for (g of groups) { elements = g.elements obj[g.key] = elements; } return obj } function Map.groupBy(array, callback) { groups = GroupBy(array, callback, property); map = new Map(); for (g of groups) { elements = g.elements map.set(g.key, elements); } return map; } GroupByΛڞ௨ͯ͠ݺΜͰΔ…

Slide 23

Slide 23 text

GroupByΛ೷͍ͯΈΔͱ… function GroupBy(arr: T [], callback): {key: string; elements: T [] }[] { groups = []; for(k = 0; k < arr.length(); k++) { /* ࡉ͔͍ॲཧ */ key = callback(arr[k]); AddValueToKeyedGroup(groups, key, arr[k]). } return groups } AddValueToKeyedGroupΛݺΜͰΔ… 0 / ճݺͼग़͞ΕΔ

Slide 24

Slide 24 text

AddValueToKeyedGroupΛ೷͍ͯΈΔͱ… function AddValueToKeyedGroup(groups: {key: string; elements: T [] }[], key, value): { for(group: groups) { if (group.key === key) { group.elements.push(value); return } } group = { key: key, elements: [value] } groups.push(group) } LFZͷݸ਺ . ճ LFZ͕ͳ͚Ε͹৽ͨʹHSPVQTʹ௥Ճ

Slide 25

Slide 25 text

ͭ·Γ͜͏ͳΔ… "EE7BMVF5P,FZFE(SPVQ 0 . 0CKFDUHSPVQ#ZPS.BQHSPVQ#Z (SPVQ#Z 0 / 0 . 0 //. ˠ0 /. Ͱ͸͋Δ ͜Ε·Ͱͩͱ.ͳͷͰ0 / Ͱ΋Αͦ͞͏ ͨͩ͠ϧʔϓ͕༨ܭʹଟΊʹճͬͯͦ͏

Slide 26

Slide 26 text

ͳΜͰ͜Μͳ͜ͱͯ͠Δͷ͔…(ߟ࡯) • ObjectͱMapͰಉ͡࢓༷(ͱ͍͏͔ڍಈ)ʹ͍ͨ͠ • key஋͕࣮૷࣌ʹະఆͰ΋ରԠͰ͖ΔΑ͏ʹ • ॻ͔ΕͯΔίʔυ͸2஋෼ྨͰࣗ໌ͳͷͰྑ͍ྫͱ͸ݴ͍ʹ͍͘ • ͜ͷΑ͏ʹ࣮૷͓͚ͯ͠͹৽͍͠key͕iteration࣌ʹݟ͔ͭͬͯ΋ɹ ରԠͰ͖Δ

Slide 27

Slide 27 text

ͪΐͬͱෆརͳϕϯν͔ͩͬͨͳ…

Slide 28

Slide 28 text

reduceଆΛվྑͯ͠ΈΔ inputArray.reduce((prevValue, currentValue) => { const key = currentValue % 2 === 0 ? 'even' : 'odd' if (prevValue.hasOwnProperty(key)) { prevValue[key].push(currentValue); } else { prevValue[key] = [currentValue]; } return prevValue; }, {}) LFZ஋͕࣮૷࣌ʹະఆͰ΋͍͍Α͏ʹ 0CKFDUHSPVQ#Zͷڍಈʹ߹ΘͤͯΔ

Slide 29

Slide 29 text

ύϑΥʔϚϯε ·͊·͊ಉ͘͡Β͍ ༗ҙͳࠩ͸ͳͦ͞͏

Slide 30

Slide 30 text

·ͱΊ

Slide 31

Slide 31 text

Array grouping Method͸·͍͍͊ͧʂ • groupingܥָ͕ʹ͔͚Δ • ͦΕҎ֎Ͱ΋ fi lter஍ࠈ͔Β͸ൈ͚ग़͢ʹ΋࢖͑ͦ͏ • ύϑΥʔϚϯε͸ҎԼʹ஫ҙ • O(NM)Ͱ͸͋Δ͕ϧʔϓճ਺͕ωοΫ? • keyͷछྨ͕࣮ߦ࣌ʹ෼͔Δ৔߹Ͱ΋͍͍Α͏ʹ… • ↑छྨ͕ݻఆͩͱͪΐͬͱ͋Εͳؾ͢Δ…

Slide 32

Slide 32 text

ࢀߟ • https://tc39.es/proposal-array-grouping/ • https://devblogs.microsoft.com/typescript/announcing- typescript-5-4-beta/#objectgroupby-and-mapgroupby • https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/ Global_Objects/Object/groupBy • https://github.com/tc39/proposal-array-grouping/