object oriented – A Paragraph Merger with Removing Overlapped Duplicated Lines in C#

I am trying to make a paragraph merger that takes multiple paragraphs and output a concatenated result with removing the duplicated overlapped lines due to redundancy. Each input paragraph is with the follows specifications.

The output merged paragraph follows the rules as below.

  • Paragraph input to Update method is concatenated after the previous input.

  • If the line(s) from the start of the paragraph input to Update method is / are sequenced same (overlapped) as the end of the previous input, just keep single copy of the sequenced duplicated lines.

  • The definition of duplicated lines here:

    • The content in two line should be totally the same, no “partial overlapping” cases need to be considered.

    • The content sequence in two blocks of lines should be totally the same.

Example Input and Output

Besides the rules, here’s a use case.

  • Inputs

    Input paragraph 1 example:

    Code Review is a question and answer site for seeking peer review of your code.
    It's built and run by you as part of the Stack Exchange network of Q&A sites.
    We're working together to improve the skills of programmers worldwide by taking working code and making it better.
    We're a little bit different from other sites. Here's how:
    Ask questions, get answers, no distractions
    This site is all about getting answers.
    It's not a discussion forum.
    There's no chit-chat.
    

    Input paragraph 2 example:

    We're a little bit different from other sites. Here's how:
    Ask questions, get answers, no distractions
    This site is all about getting answers.
    It's not a discussion forum.
    There's no chit-chat.
    Good answers are voted up and rise to the top.
    The best answers show up first so that they are always easy to find.
    The person who asked can mark one answer as "accepted".
    Accepting doesn't mean it's the best answer, it just means that it worked for the person who asked.
    Get answers to practical, detailed questions
    Focus on questions about an actual problem you have faced.
    Include details about what you have tried and exactly what you are trying to do.
    
  • Expected Output

    enter image description here

    The two block of text are the same, so keep single overlapped part after merging.

    enter image description here

    Code Review is a question and answer site for seeking peer review of your code.
    It's built and run by you as part of the Stack Exchange network of Q&A sites.
    We're working together to improve the skills of programmers worldwide by taking working code and making it better.
    We're a little bit different from other sites. Here's how:
    Ask questions, get answers, no distractions
    This site is all about getting answers.
    It's not a discussion forum.
    There's no chit-chat.
    Good answers are voted up and rise to the top.
    The best answers show up first so that they are always easy to find.
    The person who asked can mark one answer as "accepted".
    Accepting doesn't mean it's the best answer, it just means that it worked for the person who asked.
    Get answers to practical, detailed questions
    Focus on questions about an actual problem you have faced.
    Include details about what you have tried and exactly what you are trying to do.
    

The experimental implementation

The experimental implementation is as below.

(Serializable)
class ParagraphMerger
{
    private List<string> paragraphContents;

    public ParagraphMerger(List<string> input)
    {
        this.paragraphContents = input;
    }

    public ParagraphMerger(string() input)
    {
        this.paragraphContents = input.ToList();
    }

    public ParagraphMerger Update(List<string> input)
    {
        return Update(input.ToArray());
    }

    public ParagraphMerger Update(string() input)
    {
        bool flag = false;
        foreach (var element in input)
        {
            if (((!IsStringExist(paragraphContents, element)) || flag) && (!String.IsNullOrWhiteSpace(element)))
            {
                paragraphContents.Add(element);
                flag = true;
            }
        }
        return this;
    }

    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        foreach (var element in this.paragraphContents)
        {
            sb.AppendLine(element);
        }
        return sb.ToString();
    }

    private bool IsStringExist(List<string> strings, string target)
    {
        if (strings is null)
        {
            return false;
        }
        if (target is null)
        {
            throw new ArgumentNullException();
        }
        foreach (var element in strings)
        {
            if (element.Equals(target))
            {
                return true;
            }
        }
        return false;
    }
}

Test cases

The test case here use ParagraphMerger class with File.ReadAllText and File.WriteAllText. The content of “paragraph1.txt” is as “Input paragraph 1” above and “paragraph2.txt” is as “Input paragraph 2” above.

var paragraph1 = File.ReadAllText("paragraph1.txt").Split(new() { Environment.NewLine }, StringSplitOptions.None);
var paragraph2 = File.ReadAllText("paragraph2.txt").Split(new() { Environment.NewLine }, StringSplitOptions.None);

ParagraphMerger paragraphMerger = new ParagraphMerger(paragraph1);
paragraphMerger.Update(paragraph2);

File.WriteAllText("output.txt", paragraphMerger.ToString());
Console.WriteLine(paragraphMerger.ToString());

All suggestions are welcome. If there is any issue about:

  • Data processing performance

  • The naming and readability

  • Potential drawbacks of the implemented methods

, please let me know.