From 500fc47618014b17166ef928767f12c00257b080 Mon Sep 17 00:00:00 2001 From: Aya Morisawa Date: Fri, 9 Nov 2018 13:03:46 +0900 Subject: [PATCH] Add group function (#3175) --- src/mfm/parse/index.ts | 21 +++++++++------------ src/prelude/array.ts | 16 ++++++++++++++++ src/prelude/string.ts | 4 ++++ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/mfm/parse/index.ts b/src/mfm/parse/index.ts index 105378343..f2beec14f 100644 --- a/src/mfm/parse/index.ts +++ b/src/mfm/parse/index.ts @@ -15,6 +15,9 @@ import { TextElementSearch } from './elements/search'; import { TextElementTitle } from './elements/title'; import { TextElementUrl } from './elements/url'; import { TextElementMotion } from './elements/motion'; +import { groupOn } from '../../prelude/array'; +import * as A from '../../prelude/array'; +import * as S from '../../prelude/string'; const elements = [ require('./elements/big'), @@ -89,16 +92,10 @@ export default (source: string): TextElement[] => { i++; } - // テキストを纏める - return tokens.reduce((a, b) => { - if (a.length && a[a.length - 1].type == 'text' && b.type == 'text') { - const tail = a.pop(); - return a.concat({ - type: 'text', - content: tail.content + b.content - }); - } else { - return a.concat(b); - } - }, [] as TextElement[]); + const combineText = (es: TextElement[]): TextElement => + ({ type: 'text', content: S.concat(es.map(e => e.content)) }); + + return A.concat(groupOn(x => x.type, tokens).map(es => + es[0].type === 'text' ? [combineText(es)] : es + )); }; diff --git a/src/prelude/array.ts b/src/prelude/array.ts index 42f05dc0c..8536e486d 100644 --- a/src/prelude/array.ts +++ b/src/prelude/array.ts @@ -29,3 +29,19 @@ export function unique(xs: T[]): T[] { export function sum(xs: number[]): number { return xs.reduce((a, b) => a + b, 0); } + +export function groupBy(f: (x: T, y: T) => boolean, xs: T[]): T[][] { + const groups = [] as T[][]; + for (const x of xs) { + if (groups.length !== 0 && f(groups[groups.length - 1][0], x)) { + groups[groups.length - 1].push(x); + } else { + groups.push([x]); + } + } + return groups; +} + +export function groupOn(f: (x: T) => S, xs: T[]): T[][] { + return groupBy((a, b) => f(a) === f(b), xs); +} diff --git a/src/prelude/string.ts b/src/prelude/string.ts index cae776bc3..6149235e4 100644 --- a/src/prelude/string.ts +++ b/src/prelude/string.ts @@ -1,3 +1,7 @@ +export function concat(xs: string[]): string { + return xs.reduce((a, b) => a + b, ""); +} + export function capitalize(s: string): string { return toUpperCase(s.charAt(0)) + toLowerCase(s.slice(1)); }