TypeScript综合练习2(文本处理)

Text Processor

You’ll practice creating and transforming arrays of strings.

Hello, fellow text editing and type setting enthusiast!
I hear you have a dual interest in both TypeScript and and type scripts.
That’s great because I have a few projects for you to help me out with all of those things.

I have a collection of raw text strings that represent some of my favorite pieces of literature.
I’d like to set up code that can turn those pieces of text into print-ready lines, each capped at a maximum character width.

Before we can do any of our fancy typography work on text, we need to split text into lines.
Much of our text data is stored in strings where the only whitespace is a single " " space between words.

More specifically: I’m going to give you an array of lines - each represented as a string.
For each of those lines, give me back an array of strings (so the final result is an array of array of strings).
Each of the strings in the array has as many of the words from the first line as it can fit, as long as there’s a " " space between them.

Additionally, for each line, I’ll need the ability to align it to the left, middle, or right.
Alignment means adding spaces to the beginning and/or end of the string to fit it to a specified character width.

Can you type this text processor up for me, fellow typography practitioner?

Setup

In one terminal, run the TypeScript compiler via the tsc script.
For example, to start the TypeScript compiler in watch mode:

npm run tsc -- --watch

In another terminal, run Jest via the test script.
For example, to start tests in watch mode:

npm run test -- --watch

Specification

In index.ts, export an alignTexts function.

Parameters:

  1. texts: An array of strings
  2. options: An object with the following properties:
    • align (optional): Whether to align to the left (default), middle, or right
    • width: Maximum character width for each processed line

Return type: An array of array of strings.

Examples

In this first example, each output string must be 3 characters long.
The first string can fit "ab" but can’t fit the additional word "c" because that would be 4 characters ("ab c").
The second string can git "c" and "d" with a space between them.

  • Input: alignTexts(["ab c d"], { width: 3 })

  • Output:

    [["ab ", "c d"]]
    

Here, there are three lines to be split, and each becomes one of the arrays in the output array.
align: "right" indicates that spaces must be added before characters (to their left), not after them (to their right).
The first line can only fit one word (first "ab", then "cd") in the allowed 4 spaces.
The second line again can only fit one word in its allowed spaces.
The third line is the only one that can fit two words together: "a" and "bc", which together with a space take up 4 characters.

  • Input: alignTexts(["ab cd", "abc def", "a bc def"], { align: "right", width: 4 })

  • Output:

    [
    	["  ab", "  cd"],
    	[" abc", " def"],
    	["a bc", " def"]
    ]
    

This last example shows aligning text to the middle.
If there’s an extra space, it’s added to the right (at the end).

  • Input: alignTexts(["a", "ab", "abc", "abcd"], { align: "middle", width: 4 })

  • Output:

    [[" a  "], [" ab "], ["abc "], ["abcd"]]
    

Files

  • index.ts: Add your alignTexts function and type annotations here
  • index.test.ts: Tests verifying your alignTexts function and type annotations
  • solution.ts: Solution code
    • solution-alternate.ts: Alternate solution code that uses a more functional approach

Notes

  • text.split(" ") is sufficient to split the original text into an array of words.
    • Don’t worry about spaces being off: words will only ever be separated by a single " " space.

代码

export type AlignmentOptions = {
	align?: "left" | "middle" | "right";
	width: number;
};

export function alignTexts(texts: string[], options: AlignmentOptions) {
	const alignedTextsLines: string[][] = [];

	for (const text of texts) {
		const lines = splitLines(text, options.width);
		const aligned = alignLines(lines, options);

		alignedTextsLines.push(aligned);
	}

	return alignedTextsLines;
}

function splitLines(text: string, width: number) {
	const lines: string[] = [];
	let line = "";

	for (const word of text.split(" ")) {
		if (line === "") {
			line = word;
		} else if (line.length + word.length < width) {
			line += ` ${word}`;
		} else {
			lines.push(line);
			line = word;
		}
	}

	lines.push(line);

	return lines;
}

function alignLines(
	lines: string[],
	{ align = "left", width }: AlignmentOptions
) {
	const aligned: string[] = [];

	for (const line of lines) {
		const remainingSpaces = width - line.length;
		let newLine = line;

		if (remainingSpaces) {
			switch (align) {
				case "left":
					for (let i = 0; i < remainingSpaces; i += 1) {
						newLine += " ";
					}
					break;

				case "middle":
					for (let i = 0; i < Math.ceil(remainingSpaces / 2); i += 1) {
						newLine += " ";
					}

					for (let i = 0; i < Math.floor(remainingSpaces / 2); i += 1) {
						newLine = " " + newLine;
					}

					break;

				case "right":
					for (let i = 0; i < remainingSpaces; i += 1) {
						newLine = " " + newLine;
					}
					break;
			}
		}

		aligned.push(newLine);
	}

	return aligned;
}

let result = alignTexts(["abc def", "abc def ghi"], { align: "right", width: 5 });
console.log(result)

结果

[ [ '  abc', '  def' ], [ '  abc', '  def', '  ghi' ] ]

另一种解法

export type AlignmentOptions = {
	align?: "left" | "middle" | "right";
	width: number;
};

export function alignTexts(texts: string[], options: AlignmentOptions) {
	return texts.map((text) =>
		alignLines(splitLines(text, options.width), options)
	);
}

function splitLines(text: string, width: number) {
	const lines: string[] = [];
	let line = "";

	for (const word of text.split(" ")) {
		if (line === "") {
			line = word;
		} else if (line.length + word.length < width) {
			line += ` ${word}`;
		} else {
			lines.push(line);
			line = word;
		}
	}

	lines.push(line);

	return lines;
}

const aligners = {
	left: (line: string, width: number) => line.padEnd(width),
	middle: (line: string, width: number) => {
		const remainingSpaces = width - line.length;

		return remainingSpaces
			? [
					" ".repeat(Math.floor(remainingSpaces / 2)),
					line,
					" ".repeat(Math.ceil(remainingSpaces / 2)),
			  ].join("")
			: line;
	},
	right: (line: string, width: number) => line.padStart(width),
};

function alignLines(
	lines: string[],
	{ align = "left", width }: AlignmentOptions
) {
	return lines.map((line) => aligners[align](line, width));
}


let result = alignTexts(["abc def", "abc def ghi"], { align: "right", width: 5 });
console.log(result)

相关推荐

  1. TypeScript综合练习2文本处理

    2024-05-10 06:48:09       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-10 06:48:09       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-10 06:48:09       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-10 06:48:09       82 阅读
  4. Python语言-面向对象

    2024-05-10 06:48:09       91 阅读

热门阅读

  1. 条形码获取商品信息

    2024-05-10 06:48:09       32 阅读
  2. 笨蛋学C++ 之 CMake的使用

    2024-05-10 06:48:09       27 阅读
  3. webpack进阶 -- 自定义Plugin,Loader封装&打包优化

    2024-05-10 06:48:09       28 阅读
  4. 【八股系列】vue的双向绑定原理是什么?

    2024-05-10 06:48:09       35 阅读
  5. ELK+kafka日志采集

    2024-05-10 06:48:09       27 阅读
  6. MySQL变量的定义与应用

    2024-05-10 06:48:09       28 阅读
  7. Node.js身份证实名认证接口、身份证识别API

    2024-05-10 06:48:09       28 阅读
  8. 第七十五章 锁定 Apache (UNIX® Linux macOS)

    2024-05-10 06:48:09       29 阅读
  9. Node.js发票ocr识别、发票查验接口

    2024-05-10 06:48:09       28 阅读
  10. MySQL中的字符集陷阱:为何避免使用UTF-8

    2024-05-10 06:48:09       24 阅读