lodash#flatMap TypeScript Examples
The following examples show how to use
lodash#flatMap.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: score.ts From fishbowl with MIT License | 6 votes |
export function teamScore(
team: Team,
turns: CurrentGameSubscription["games"][0]["turns"],
players: CurrentGameSubscription["games"][0]["players"]
) {
const teamPlayerIds = filter(players, (player) => player.team === team).map(
(player) => player.id
)
const teamTurns = filter(turns, (turn) =>
teamPlayerIds.includes(turn.player_id)
)
return flatMap(teamTurns, (turn) => turn.completed_card_ids).length
}
Example #2
Source File: traceSummary.ts From erda-ui with GNU Affero General Public License v3.0 | 6 votes |
export function traceSummary(spans: any = []) {
if (spans.length === 0 || !spans[0].timestamp) {
return null;
}
const duration = traceDuration(spans) || 0; // 获取span时间轴长(最大时间-最小时间)
const endpoints = fp.flow(
// 筛选出所有的终端(获取binaryAnnotations中的serviceName)
fp.flatMap(endpointsForSpan),
fp.uniqWith(endpointEquals),
)(spans);
const { traceId, timestamp } = spans[0];
const spanTimestamps = getSpanTimestamps(spans);
const errorType = getTraceErrorType(spans);
return {
traceId,
timestamp,
duration,
spanTimestamps,
endpoints,
errorType,
};
}
Example #3
Source File: traceSummary.ts From erda-ui with GNU Affero General Public License v3.0 | 6 votes |
function getSpanTimestamps(spans: any) {
return flatMap(spans, (span) =>
getServiceNames(span).map((serviceName) => ({
name: serviceName,
timestamp: span.timestamp,
duration: span.duration,
})),
);
}
Example #4
Source File: traceSummary.ts From erda-ui with GNU Affero General Public License v3.0 | 6 votes |
// What's the total duration of the spans in this trace?
// 最后结束的(时间戳+耗时最大)- 第一个调用的时间戳
export function traceDuration(spans: any) {
function makeList({ timestamp, duration }: any) {
if (!timestamp) {
return [];
} else if (!duration) {
return [timestamp];
}
return [timestamp, timestamp + duration];
}
// turns (timestamp, timestamp + duration) into an ordered list
const timestamps = fp.flow(fp.flatMap(makeList), fp.sortBy(identity))(spans);
if (timestamps.length < 2) {
return null;
}
const firstTime = head(timestamps);
const lastTime = last(timestamps);
return lastTime - firstTime;
}
Example #5
Source File: turn.ts From fishbowl with MIT License | 6 votes |
export function drawableCards(
turns: CurrentGameSubscription["games"][0]["turns"],
cards: CurrentGameSubscription["games"][0]["cards"]
) {
const allCompletedCardIds = flatMap(turns, (turn) => turn.completed_card_ids)
const maxCount = max(values(countBy(allCompletedCardIds)))
let completedCardIdsForRound = filter(
groupBy(allCompletedCardIds),
(arr) => arr.length === maxCount
).map((arr) => arr[0])
const remainingIdsForRound = difference(
cards.map((card) => card.id),
completedCardIdsForRound
)
if (remainingIdsForRound.length === 0) {
return cards
} else {
return filter(cards, (card) => remainingIdsForRound.includes(card.id))
}
}
Example #6
Source File: quick-fix.ts From ui5-language-assistant with Apache License 2.0 | 6 votes |
export function diagnosticToCodeActionFix(
document: TextDocument,
diagnostics: Diagnostic[],
ui5Model: UI5SemanticModel
): CodeAction[] {
const documentText = document.getText();
// We prefer to parse the document again to avoid cache state handling
const { cst, tokenVector } = parse(documentText);
const xmlDocAst = buildAst(cst as DocumentCstNode, tokenVector);
const codeActions = flatMap(diagnostics, (diagnostic) => {
switch (diagnostic.code) {
case validations.NON_STABLE_ID.code: {
// non stable id
return computeCodeActionsForQuickFixStableId({
document,
xmlDocument: xmlDocAst,
nonStableIdDiagnostic: diagnostic,
ui5Model,
});
}
default:
return [];
}
});
return codeActions;
}
Example #7
Source File: Template.tsx From easy-email with MIT License | 6 votes |
export function Template(props: TemplateProps) {
let formatChildren = props.children;
if (Array.isArray(formatChildren)) {
formatChildren = flatMap(formatChildren);
}
return (
<MjmlBlock
attributes={omit(props, ['data', 'children', 'value'])}
type={BasicType.TEMPLATE}
value={{ idx: props.idx }}
>
{formatChildren}
</MjmlBlock>
);
}
Example #8
Source File: cardinality-of-aggregation.ts From ui5-language-assistant with Apache License 2.0 | 6 votes |
/**
* @param aggregationElem The aggregation from which we will get all its subElements at the same depth.
*
* For example - Given XMLSnippet aggregationElem param `headerToolbar`.
* The function will return an array of `Toolbar` and `tnt:ToolHeader` elements
*
* ```
* <headerToolbar>
* <Toolbar></Toolbar>
* </headerToolbar>
* <headerToolbar>
* <tnt:ToolHeader></tnt:ToolHeader>
* </headerToolbar>
* ```
**/
function getAllSubElementsAtSameDepth(
aggregationElem: XMLElement
): XMLElement[] {
// We can never reach this case - if it's the root tag, it will never be an aggregation
/* istanbul ignore next */
if (aggregationElem.parent.type !== "XMLElement") {
return [];
}
const aggregationParent = aggregationElem.parent;
const sameNameAggregations = filter(
aggregationParent.subElements,
(_) => _.name === aggregationElem.name && !isEmpty(_.subElements)
);
const allSubElementsAtSameDepth = flatMap(sameNameAggregations, (_) => {
return _.subElements;
});
return allSubElementsAtSameDepth;
}
Example #9
Source File: non-unique-id.ts From ui5-language-assistant with Apache License 2.0 | 6 votes |
export function validateNonUniqueID(xmlDoc: XMLDocument): NonUniqueIDIssue[] {
const idCollector = new IdsCollectorVisitor();
accept(xmlDoc, idCollector);
const idsToXMLElements = idCollector.idsToXMLElements;
const duplicatedIdsRecords = pickBy(idsToXMLElements, (_) => _.length > 1);
const allIDsIssues: NonUniqueIDIssue[] = flatMap(
duplicatedIdsRecords,
buildIssuesForSingleID
);
return allIDsIssues;
}
Example #10
Source File: find-classes-matching-type.ts From ui5-language-assistant with Apache License 2.0 | 6 votes |
export function classIsOfType(
clazz: UI5Class,
type: UI5Class | UI5Interface
): boolean {
const clazzAndSuperClasses = getSuperClasses(clazz).concat([clazz]);
const superInterfaces = flatMap(clazzAndSuperClasses, (_) => _.implements);
return (
includes(clazzAndSuperClasses, type) || includes(superInterfaces, type)
);
}
Example #11
Source File: turn.ts From fishbowl with MIT License | 5 votes |
export function completedCardIds(
turns: CurrentGameSubscription["games"][0]["turns"]
) {
return flatMap(turns, (turn) => turn.completed_card_ids)
}
Example #12
Source File: validate-xml-views.ts From ui5-language-assistant with Apache License 2.0 | 5 votes |
visitXMLAttribute(node: XMLAttribute): void {
const nodeIssues = flatMap(this.validators.attribute, (_) =>
_(node, this.model)
);
this.collectedIssues = this.collectedIssues.concat(nodeIssues);
}
Example #13
Source File: traceConvert.ts From erda-ui with GNU Affero General Public License v3.0 | 5 votes |
childrenToList = (entry: Entry) => {
const fpSort = (fn: ((a: Entry, b: Entry) => number) | undefined) => (list: Entry[]) => list.sort(fn);
const deepChildren: Array<Entry['span']> = fp.flow(
fpSort((e1: Entry, e2: Entry) => compareSpan(e1.span, e2.span)),
fp.flatMap(childrenToList),
)(entry.children || []);
return [entry.span, ...deepChildren];
}
Example #14
Source File: traceConvert.ts From erda-ui with GNU Affero General Public License v3.0 | 5 votes |
traceConvert = (traces: MONITOR_TRACE.ITrace): Trace => {
const { spans: oldSpans, duration: durationNs, depth, spanCount, serviceCount } = traces;
if (!oldSpans?.length) {
return {} as Trace;
}
const summary = traceSummary(oldSpans);
const duration = durationNs / 1000;
const spanDepths = toSpanDepths(oldSpans);
const groupByParentId = groupBy(oldSpans, (s) => s.parentSpanId);
let traceTimestamp = 0;
const spans = flatMap(getRootSpans(oldSpans), (rootSpan) =>
childrenToList(createSpanTreeEntry(rootSpan, oldSpans)),
).map((span, index) => {
if (!index) {
traceTimestamp = span.startTime;
}
const spanDuration = span.duration / 1000;
const spanStartTs = span.startTime || traceTimestamp;
const spanDepth = spanDepths[span.id] || 1;
const width = ((spanDuration || 0) / duration) * 100;
const errorType = span.tags.error ? 'critical' : 'none';
const left = ((spanStartTs - traceTimestamp) / durationNs) * 100;
return {
...span,
spanId: span.id,
parentId: span.parentSpanId || null,
duration: spanDuration,
durationStr: mkDurationStr(spanDuration),
left: left >= 100 ? 0 : left,
width: width < 0.1 ? 0.1 : width,
depth: (spanDepth + 2) * 5,
depthClass: (spanDepth - 1) % 6,
children: (groupByParentId[span.id] || []).map((s) => s.id).join(','),
annotations: (span.annotations || []).map((a) => ({
isCore: Constants.CORE_ANNOTATIONS.indexOf(a.value) !== -1,
left: ((a.timestamp - spanStartTs) / spanDuration) * 100,
message: a.message,
value: ConstantNames[a.value] || a.value,
timestamp: a.timestamp,
relativeTime: mkDurationStr(a.timestamp - traceTimestamp),
width: 8,
})),
errorType,
};
});
const timeMarkers = [0, 0.2, 0.4, 0.6, 0.8, 1].map((p, index) => ({
index,
time: mkDurationStr(duration * p),
}));
const timeMarkersBackup = timeMarkers;
const spansBackup = spans;
return {
...summary,
totalSpans: spanCount,
services: serviceCount,
duration: mkDurationStr(duration),
depth,
spans,
spansBackup,
timeMarkers,
timeMarkersBackup,
};
}
Example #15
Source File: validate-xml-views.ts From ui5-language-assistant with Apache License 2.0 | 5 votes |
visitXMLElement(node: XMLElement): void {
const nodeIssues = flatMap(this.validators.element, (_) =>
_(node, this.model)
);
this.collectedIssues = this.collectedIssues.concat(nodeIssues);
}
Example #16
Source File: validate-xml-views.ts From ui5-language-assistant with Apache License 2.0 | 5 votes |
visitXMLDocument(node: XMLDocument): void {
const nodeIssues = flatMap(this.validators.document, (_) =>
_(node, this.model)
);
this.collectedIssues = this.collectedIssues.concat(nodeIssues);
}
Example #17
Source File: spread-sheet-totals-spec.ts From S2 with MIT License | 4 votes |
describe('Spreadsheet Totals Tests', () => {
let spreadsheet: PivotSheet;
const dataCfg = assembleDataCfg();
beforeEach(() => {
spreadsheet = new PivotSheet(getContainer(), dataCfg, assembleOptions());
});
test('should render total nodes on row header', () => {
spreadsheet.setOptions({ totals: TOTALS_OPTIONS });
spreadsheet.render();
const totalNodes = spreadsheet.facet.layoutResult.rowNodes.filter(
(node) => node.isTotals,
);
expect(totalNodes).toHaveLength(3);
// grand total
const grandTotalNode = totalNodes.filter(
(node) => node.isGrandTotals && node.level === 0,
);
expect(grandTotalNode).toBeDefined();
// sub total
const provinceSubTotalNodes = totalNodes.filter(
(node) => node.field === 'city' && node.level === 1,
);
expect(provinceSubTotalNodes).toHaveLength(2); // 四川、浙江
});
test('should render total nodes on col header', () => {
spreadsheet.setOptions({ totals: TOTALS_OPTIONS });
spreadsheet.render();
const totalNodes = spreadsheet.facet.layoutResult.colNodes.filter(
(node) => node.isTotals,
);
expect(totalNodes).toHaveLength(3);
// grand total
const grandTotalNode = totalNodes.filter(
(node) => node.isGrandTotals && node.level === 0,
);
expect(grandTotalNode).toBeDefined();
// sub total
const typeSubTotalNodes = totalNodes.filter(
(node) => node.field === 'sub_type' && node.level === 1,
);
expect(typeSubTotalNodes).toHaveLength(2); // 家具、办公用品
});
test('should not render grand total nodes', () => {
spreadsheet.setOptions({
totals: merge({}, TOTALS_OPTIONS, {
row: {
showGrandTotals: false,
},
col: {
showGrandTotals: false,
},
}),
});
spreadsheet.render();
const { rowNodes, colNodes } = spreadsheet.facet.layoutResult;
const totalNodes = flatMap([rowNodes, colNodes], (nodes) => {
return nodes.filter((node) => node.isTotals);
});
expect(totalNodes.filter((node) => node.isGrandTotals)).toHaveLength(0);
expect(totalNodes).toHaveLength(4);
});
test('should not render sub total nodes when always=false', () => {
const anotherDataCfg = assembleDataCfg() as S2DataConfig;
/**
* 构建专用数据集
* 行头:浙江省下有多个城市、四川省下只有成都
* 列头:办公用品下有两个维度,家具下只有桌子
*/
const filterCond = (item) =>
(item.province === '浙江省' || item.city === '成都市') &&
(item.type === '办公用品' || item.sub_type === '桌子');
anotherDataCfg.data = anotherDataCfg.data.filter(filterCond);
anotherDataCfg.totalData = anotherDataCfg.totalData.filter(filterCond);
spreadsheet.setDataCfg(anotherDataCfg);
spreadsheet.setOptions({
totals: merge({}, TOTALS_OPTIONS, {
row: {
showSubTotals: {
always: false,
},
},
col: {
showSubTotals: {
always: false,
},
},
} as S2Options['totals']),
});
spreadsheet.render();
const findSubTotalNode = (
nodes: Node[],
parentLabel: string,
subTotalDimension: string,
) => {
return nodes.find(
(node) =>
node.parent.label === parentLabel &&
node.field === subTotalDimension &&
node.isSubTotals,
);
};
const { rowNodes, colNodes } = spreadsheet.facet.layoutResult;
// 当子维度只有一个时,不展示小计节点
expect(findSubTotalNode(rowNodes, '浙江省', 'city')).toBeDefined();
expect(findSubTotalNode(rowNodes, '四川省', 'city')).toBeUndefined();
expect(findSubTotalNode(colNodes, '家具', 'sub_type')).toBeUndefined();
expect(findSubTotalNode(colNodes, '办公用品', 'sub_type')).toBeDefined();
});
});
Example #18
Source File: index.tsx From fishbowl with MIT License | 4 votes |
function EndGame() {
const { t } = useTranslation()
const currentGame = React.useContext(CurrentGameContext)
const currentPlayer = React.useContext(CurrentPlayerContext)
const titleClasses = useTitleStyle()
const [redirectHome, setRedirectHome] = React.useState(false)
const turnsByPlayer = new Map()
currentGame.turns.forEach((turn) => {
turnsByPlayer.set(
turn.player_id,
reject(
(turnsByPlayer.get(turn.player_id) || []).concat([
turn.completed_card_ids,
]),
(arr) => isEmpty(arr)
)
)
})
const scoresByPlayer = new Map()
turnsByPlayer.forEach((value, key) => {
scoresByPlayer.set(key, flatMap(value).length)
})
let highScore = -1
scoresByPlayer.forEach((value, key) => {
if (value > highScore) {
highScore = value
}
})
const highScorePlayers = filter(
currentGame.players,
(player) => scoresByPlayer.get(player.id) === highScore
)
const redScore = teamScore(Team.Red, currentGame.turns, currentGame.players)
const blueScore = teamScore(Team.Blue, currentGame.turns, currentGame.players)
const tie = redScore === blueScore
const winningTeam = redScore > blueScore ? Team.Red : Team.Blue
const shareContent = t(
"end.shareContent",
"Just had a great time playing {{ url }} online, you should check it out!",
{ url: "fishbowl-game.com" }
)
return (
<>
{redirectHome && <Redirect to={routes.root}></Redirect>}
<Grid container direction="column" spacing={2}>
<Grid item style={{ textAlign: "center" }}>
<Typography variant="h4" className={titleClasses.title}>
{t("end.title", "Game Over")}
</Typography>
</Grid>
<Grid item style={{ textAlign: "center" }}>
<Box style={{ fontSize: "24px", lineHeight: "0.9" }}>
{<span style={{ color: TeamColor[Team.Red] }}>{redScore}</span>}
{" - "}
{<span style={{ color: TeamColor[Team.Blue] }}>{blueScore}</span>}
</Box>
</Grid>
<Grid item>
<Divider variant="fullWidth"></Divider>
</Grid>
<Grid item>
{tie
? t("end.result.tie", "It's a tie! Play again to break it.")
: t("end.result.win", "{{ teamName }} wins! Bask in the glory.", {
teamName: t(
`teams.teamName.${winningTeam}`,
`Team ${winningTeam}`
).toLocaleUpperCase(),
})}
</Grid>
{!isEmpty(highScorePlayers) && (
<Grid item>
<Trans
t={t}
i18nKey="end.highScore"
count={highScorePlayers.length}
values={{ highScore }}
tOptions={{
defaultValue_plural:
"<0>{{playerUsernames}}</0> put the team on their back. They got their team to guess the most number of cards ({{ highScore }}!), across all rounds.",
}}
>
<PlayerChipList players={highScorePlayers}>
{{ playerUsernames: null }}
</PlayerChipList>
{
" put the team on their back. They got their team to guess the most number of cards ({{ highScore }}!), across all rounds."
}
</Trans>
</Grid>
)}
<Grid item>
{t("end.yourScore", "You scored {{ score }} across all rounds.", {
score: scoresByPlayer.get(currentPlayer.id) || 0,
})}
</Grid>
<Grid item>
<Divider variant="fullWidth"></Divider>
</Grid>
<Grid
item
container
direction="column"
justify="center"
alignItems="center"
>
<Box pb={2}>
{t(
"end.thanks.share",
"Thanks for playing -- if you had fun, share it with your friends!"
)}
</Box>
<Grid container justify="center" spacing={2}>
<Grid item>
<TwitterShareButton
url={"fishbowl-game.com"}
title={shareContent}
>
<TwitterIcon size={50} round />
</TwitterShareButton>
</Grid>
<Grid item>
<FacebookShareButton
url={"fishbowl-game.com"}
title={shareContent}
>
<FacebookIcon size={50} round />
</FacebookShareButton>
</Grid>
</Grid>
<Trans t={t} i18nKey="end.thanks.support">
<Box pb={1} pt={2}>
Or support the project by
</Box>
<Box py={2}>
<BuyMeACoffeeButton>Buying us a coffee</BuyMeACoffeeButton>
</Box>
<Box py={1}>
<Link href="https://forms.gle/L9qWMsnAUghXqqxE9" target="_blank">
sharing your feedback
</Link>
, and playing again soon!
</Box>
</Trans>
</Grid>
<Grid item>
<Divider variant="fullWidth"></Divider>
</Grid>
<Grid item container justify="center">
<Box py={1}>
<Button variant="outlined" onClick={() => setRedirectHome(true)}>
{t("end.playAgainButton", "Play Again")}
</Button>
</Box>
</Grid>
</Grid>
</>
)
}
Example #19
Source File: index.tsx From fishbowl with MIT License | 4 votes |
function Play() {
const { t } = useTranslation()
const titleClasses = useTitleStyle()
const currentGame = React.useContext(CurrentGameContext)
const currentPlayer = React.useContext(CurrentPlayerContext)
const [startReview] = useStartReviewMutation()
const [
hasDismissedInstructionCard,
setHasDismissedInstructionCard,
] = React.useState(false)
const completedCardIds = flatMap(
currentGame.turns,
(turn) => turn.completed_card_ids
)
const activeTurn = last(currentGame.turns)
const activePlayer = currentGame.players.find(
(player) => player.id === activeTurn?.player_id
)
const [activeTurnPlayState, setActiveTurnPlayState] = React.useState(
playStateFromTurn(activeTurn)
)
React.useEffect(() => {
setActiveTurnPlayState(playStateFromTurn(activeTurn))
}, [activeTurn])
const secondsLeft = useSecondsLeft(activeTurnPlayState)
// countdown timer
React.useEffect(() => {
if (
activeTurnPlayState === ActiveTurnPlayState.Playing &&
secondsLeft <= 0
) {
setActiveTurnPlayState(ActiveTurnPlayState.Reviewing)
if (currentPlayer.id === activeTurn?.player_id && activeTurn?.id) {
startReview({
variables: {
currentTurnId: activeTurn.id,
},
})
}
}
}, [secondsLeft]) // eslint-disable-line react-hooks/exhaustive-deps
if (!activeTurn || !activePlayer) {
return null
}
const numCompletedCards = completedCardIds.length
const totalNumCards = currentGame.cards.length
const numRounds = currentGame.rounds.length
if (numCompletedCards === numRounds * totalNumCards) {
return <NoMoreRounds />
}
const roundMarkers = [...Array(numRounds).keys()]
let roundNum = Math.floor(numCompletedCards / totalNumCards)
const currentRoundId = currentGame.rounds[roundNum].id
const nextRoundId = currentGame.rounds[roundNum + 1]?.id
let roundMarker = numCompletedCards / totalNumCards
let round = ""
if (roundMarkers.includes(roundMarker)) {
const value = capitalize(currentGame.rounds[roundMarker].value)
round = GameRound[value as GameRound]
if (round) {
round = t(`howToPlay.round.${round.toLowerCase()}.name`, round)
} else {
round = value
}
}
const yourTurn = activePlayer.id === currentPlayer.id
const yourTeamTurn =
activePlayer.team ===
currentPlayerTeam(currentPlayer.id, currentGame.players)
let titleText = null
let content = null
if (yourTurn) {
titleText = t("play.yourTurn.title", "Your Turn")
content = (
<YourTurnContent
yourTeamPlayers={filter(
currentGame.players,
(player) => activePlayer.team === player.team
)}
cardsInBowl={drawableCards(currentGame.turns, currentGame.cards)}
secondsLeft={secondsLeft}
activePlayer={activePlayer}
activeTurn={activeTurn}
activeTurnPlayState={activeTurnPlayState}
onStart={() => {
setActiveTurnPlayState(ActiveTurnPlayState.Playing)
}}
onOutOfCards={() => {
setActiveTurnPlayState(ActiveTurnPlayState.Reviewing)
startReview({
variables: {
currentTurnId: activeTurn.id,
},
})
}}
currentRoundId={currentRoundId}
nextRoundId={nextRoundId}
/>
)
} else if (yourTeamTurn) {
titleText = t("play.yourTeam.title", "You're Guessin'")
content = (
<YourTeamTurnContent
activePlayer={activePlayer}
activeTurn={activeTurn}
/>
)
} else {
titleText = t("play.otherTeam.title", "You're Chillin'")
content = (
<OtherTeamContent activePlayer={activePlayer} activeTurn={activeTurn} />
)
}
return (
<Grid container direction="column" alignItems="center" spacing={2}>
<Grid item>
<Typography variant="h4" className={titleClasses.title}>
{titleText}
</Typography>
</Grid>
<Grid item>
<Divider
variant="middle"
style={{
width: 150,
height: 2,
backgroundColor:
TeamColor[
currentPlayerTeam(currentPlayer.id, currentGame.players) as Team
] || grey[600],
}}
/>
</Grid>
{round && !hasDismissedInstructionCard && (
<Grid item>
<Box mb={1}>
<GameRoundInstructionCard
round={round}
roundNumber={Number(roundMarker + 1)}
onDismiss={() => {
setHasDismissedInstructionCard(true)
}}
/>
</Box>
</Grid>
)}
<Grid item>
<TurnContextPanel
secondsLeft={Math.round(Math.max(secondsLeft, 0)) || 0}
/>
</Grid>
<Grid item>{content}</Grid>
{currentPlayer.role === PlayerRole.Host && (
<Grid item>
<HostControls
activePlayer={activePlayer}
activeTurn={activeTurn}
currentRoundId={currentRoundId}
/>
</Grid>
)}
</Grid>
)
}