Консоль перенос слов


Я написал текстовый квест, а сегодня я посмотрел на него, чтобы увидеть, как я сделал перенос слов (чтобы использовать в новом проекте); мне интересно, если я сделал это правильно. Я понимаю, что я мог бы использовать массив вместо списка и удалить 2 зависимости от класса, но хотел некоторые другие отзывы, как я, возможно, пропустил что-то очевидное.

    public static string GetBorderedText(string Input, int AbsoluteLength, bool splitLines = true, int Offset = -4)
    {
        string outputString = "";

        if(Input.Length > AbsoluteLength + Offset && splitLines)
        {
            List<string> words = Input.Split(' ').ToList();
            string lineConstruction = "";

            foreach (string s in words)
            {
                if (lineConstruction.Length + s.Length + 1 >= AbsoluteLength + Offset)
                {
                    outputString += "+ " + GetPaddedSubstring(lineConstruction, AbsoluteLength, Offset) + " +" + Environment.NewLine;
                    lineConstruction = "";
                    lineConstruction += s + " ";
                }
                else
                {
                    lineConstruction += s + " ";
                }
            }

            outputString += "+ " + GetPaddedSubstring(lineConstruction, AbsoluteLength, Offset) + " +";

            return outputString;
        }
        else
        {
            outputString = "+ " + GetPaddedSubstring(Input, AbsoluteLength, Offset) + " +";
            return outputString;
        }
    }

где GetPaddedSubstring используется для получения подстроки мягкий до определенной длины.

    public static string GetPaddedSubstring(string Input, int AbsoluteLength, int Offset)
    {
        int targetLength = AbsoluteLength + Offset;
        string output = "";

        if(Input.Length > targetLength)
        {
            return Input.Substring(0, targetLength);
        }
        else
        {
            output = Input.PadRight(targetLength);

            return output;
        }
    }

Наконец, для некоторых примеров. GetBorderedText может принять в что-то вроде

"This room looks sturdy, but old. Lots of storage and containers. There is a door on the far side."

И вернуть что-то вроде этого.

+ This room looks sturdy, but old. Lots of storage and containers. There is a door     +
+ on the far side.                                                                     +

В + на стороне просто, чтобы создать хорошее границе в консоли окно. (Отсюда и -4 по умолчанию на зачет)



360
4
задан 26 марта 2018 в 03:03 Источник Поделиться
Комментарии
3 ответа


GetBorderedText(string Input, int AbsoluteLength, bool splitLines = true, int Offset = -4)

Вы весьма непоследовательны с параметрами именования. Некоторые из них находятся в PascalCase пока только одна имеет правильную верблюжьего. Это делает ваш код выглядит странно и непрофессионально.



if (Input.Length > AbsoluteLength + Offset && splitLines)

Таких условиях лучше сохраняется в переменной, которая описывает то, что его целью является и разделить на два. Рассматривайте это:

var wrapRequired = input.Length > absoluteLength + offset;
if (wrapRequired && canWrap)



input.Split(' ').ToList()

Вам не нужно позвонить ToListэто уже массив и могут быть перечислены.



foreach (string s in words)

Если в вашей коллекции называется words затем название элемента word и не s. Это сбивает с толку, когда смотришь на код и чудеса, что s это.



lineConstruction.Length + word.Length + 1 >= absoluteLength + offset

То же самое здесь. Вы должны назвать это состояние propertly и особенно магия 1.


Другие, чем это


  • вы должны использовать StringBuilder для объединения строк в циклах, потому что это не только быстрее, но и проще в использовании.

  • сделать границы, как prefix & suffix параметры вместо того, чтобы хардкодить их (или leftBorder & rightBorder).

  • использовать переменные с более сильными именами и использовать их так, что они документируют свой код.

Как пример, как можно применить все эти предложения, вот новый код с новым методом добавления границу.

public static string CreateBorderedText(string input, int maxLength, bool canWrap = true, string prefix = "+ ", string suffix = " +")
{
const string wordSeparator = " ";

var lines = new List<string>();
var lineBuilder = new StringBuilder();
var borderLength = prefix.Length + suffix.Length;
var contentLength = maxLength - borderLength;

var wrapRequired = input.Length > contentLength;
if (wrapRequired && canWrap)
{
var words = input.Split(' ');
foreach (var word in words)
{
var projectedLength = lineBuilder.Length + word.Length + wordSeparator.Length + borderLength;
var wrap = projectedLength >= maxLength;
if (wrap)
{
PadRight(lineBuilder, contentLength);
AddBorder(lineBuilder, prefix, suffix);

lines.Add(lineBuilder.ToString());
lineBuilder.Clear();
}

lineBuilder.Append(word).Append(wordSeparator);
}
}
else
{
lineBuilder.Append(input);
}

PadRight(lineBuilder, contentLength);
AddBorder(lineBuilder, prefix, suffix);
lines.Add(lineBuilder.ToString());

return string.Join(Environment.NewLine, lines);
}

и двух помощников

private static void AddBorder(StringBuilder lineBuilder, string prefix, string suffix)
{
lineBuilder
.Insert(0, prefix)
.Append(suffix);
}

private static void PadRight(StringBuilder lineBuilder, int targetLength)
{
lineBuilder.Append(' ', targetLength - lineBuilder.Length);
}

7
ответ дан 26 марта 2018 в 08:03 Источник Поделиться

первое, что я хотел сделать, это перейти на оператор return вне, если еще заявление, потому что вы не возвращая outputString несмотря ни на что, это также приводит к перемещению на следующую строку вне ее непосредственной, если заявление, но держать его внутри оператора foreach


lineConstruction += s + " ";

Этот сухойс ваш код немного и выглядит вот так

public static string GetBorderedText(string Input, int AbsoluteLength, bool splitLines = true, int Offset = -4)
{
string outputString = "";

if(Input.Length > AbsoluteLength + Offset && splitLines)
{
List<string> words = Input.Split(' ').ToList();
string lineConstruction = "";

foreach (string s in words)
{
if (lineConstruction.Length + s.Length + 1 >= AbsoluteLength + Offset)
{
outputString += "+ " + GetPaddedSubstring(lineConstruction, AbsoluteLength, Offset) + " +" + Environment.NewLine;
lineConstruction = "";

}
lineConstruction += s + " ";
}

outputString += "+ " + GetPaddedSubstring(lineConstruction, AbsoluteLength, Offset) + " +";
}
else
{
outputString = "+ " + GetPaddedSubstring(Input, AbsoluteLength, Offset) + " +";
}
return outputString;
}


вы должны избавиться от output строковой переменной от GetPaddedSubstring() способ, потому что вы действительно не нужно.
внутри блока if вы вернуть значение сразу же, но в другом заявлении вы присвоить значение переменной, а затем вернуть значение переменной, пропустить этот шаг и просто возвращать значение, как это

public static string GetPaddedSubstring(string Input, int AbsoluteLength, int Offset)
{
int targetLength = AbsoluteLength + Offset;
if(Input.Length > targetLength)
{
return Input.Substring(0, targetLength);
}
else
{
return = Input.PadRight(targetLength);
}
}

3
ответ дан 26 марта 2018 в 03:03 Источник Поделиться

Вот ваш код, немного прибрался (даже сняли 2 зависимостей):

namespace Tests
{
using System;

class Program
{
private static void Main(string[] args)
{
Console.WriteLine(GetBorderedText("This room looks sturdy, but old. Lots of storage and containers. There is a door on the far side.", 80));
Console.ReadKey();
}

private static string GetBorderedText(string input, int maxLength, bool splitLines = true, int offset = -4)
{
if (input.Length <= maxLength + offset && splitLines)
return $"+ {GetPaddedSubstring(input, maxLength, offset)} +";

var outputString = string.Empty;
var lineConstruction = string.Empty;

foreach (var s in input.Split(' '))
{
if (lineConstruction.Length + s.Length + 1 >= maxLength + offset)
{
outputString += $"+ {GetPaddedSubstring(lineConstruction, maxLength, offset)} +{Environment.NewLine}";

lineConstruction = string.Empty;
}

lineConstruction += $"{s} ";
}

outputString += $"+ {GetPaddedSubstring(lineConstruction, maxLength, offset)} +";

return outputString;
}

private static string GetPaddedSubstring(string input, int maxLength, int offset)
{
var targetLength = maxLength + offset;

if (input.Length > targetLength)
return input.Substring(0, targetLength);

return input.PadRight(targetLength);

}
}
}

Вы могли бы поставить StringBuilder в там, как уже упоминалось ранее, но если количество строк не много, я бы не стал заморачиваться.

-2
ответ дан 29 марта 2018 в 02:03 Источник Поделиться