【问题标题】:Separate a string into a list where is not in a collection Dictionary将字符串分隔到不在集合字典中的列表中
【发布时间】:2018-05-17 07:26:31
【问题描述】:

这是我的句子:

您在 StackOverFlow.com 上提问

现在我有一个字符串列表的字典集合:

Dictionary<int, List<string>> collections = new Dictionary<int, List<string>>()
{
    { 1, new List<string>() { "You", "your" } },
    { 2, new List<string>() { "Stack", "Flow" } },
};

我需要将我的字符串拆分为一个字符串列表,其中集合中的字符串不存在,并将每个 List 键放在它的位置,以便我知道我从哪个列表中找到列表的项目:

例如,我这句话的输出是:

“1”、“问”、“1”、“关于“的问题”、“2”、“结束”、“2”、“.com”

如您所见,此处未列出集合中的所有单词。相反,他们的列表键被替换。 我所知道的是,我可以通过以下代码检查我的字符串是否包含另一个列表的任何单词:

listOfStrings.Any(s=>myString.Contains(s));

但不知道如何检查列表的整个字典集合并获取每个列表键并将其替换为新的字符串列表。

【问题讨论】:

  • String.Split(String[], Int32, StringSplitOptions) - 那么你需要将你的 collections 展平为一个独特的数组,然后就可以了
  • @Rafalon - 你如何将 StackOverFlow 拆分为 Stack,Over,Flow ?
  • @bommelding this way
  • 你不应该用更多的问题来更新你的问题,如果你想扩展你的问题,你应该创建一个新的问题。现在所有现有答案都无效...

标签: c# linq


【解决方案1】:
static void Main()
{
    string myString = "You ask your questions on StackOverFlow.com";
    string[] collection = new string[]
    {
        "You",
        "your",
        "Stack",
        "Flow"
    };

    var splitted = myString.Split(collection, StringSplitOptions.RemoveEmptyEntries);

    foreach(var s in splitted)
    {
        Console.WriteLine("\""+s+"\"");
    }
}

将导致:

" ask "
" questions on "
"Over"
".com"

您可以使用SelectMany 来扁平化您的collections


根据您的编辑:

static void Main()
{
    string myString = "You ask your questions on StackOverFlow.com";

    Dictionary<int, List<string>> collections = new Dictionary<int, List<string>>()
    {
        { 1, new List<string>() { "You", "your" } },
        { 2, new List<string>() { "Stack", "Flow" } },
    };

    foreach(var index in collections.Keys)
    {
        foreach(var str in collections[index])
        {
            myString = myString.Replace(str, index.ToString());
        }
    }

    Console.WriteLine(myString);
}

给予:

1 ask 1 questions on 2Over2.com

static void Main()
{
    string myString = "You ask your questions on StackOverFlow.com";

    Dictionary<int, List<string>> collections = new Dictionary<int, List<string>>()
    {
        { 1, new List<string>() { "You", "your" } },
        { 2, new List<string>() { "Stack", "Flow" } },
    };

    var tempColl = collections.SelectMany(c => c.Value);
    // { "You", "your", "Stack", "Flow" }

    string separator = String.Join("|", tempColl);
    // "You|your|Stack|Flow"

    var splitted = Regex.Split(myString, @"("+separator+")");
    // { "", "You", " ask ", "your", " questions on ", "Stack", "Over", "Flow", ".com" }

    for(int i=0;i<splitted.Length;i++)
    {
        foreach(var index in collections.Keys)
        {
            foreach(var str in collections[index])
            {
                splitted[i] = splitted[i].Replace(str, index.ToString());
            }
        }
    }

    foreach(var s in splitted)
    {
        Console.WriteLine("\""+s+"\"");
    }
}

给予:

""
"1"
" ask "
"1"
" questions on "
"2"
"Over"
"2"
".com"

注意开头的空字符串是because

如果在输入字符串的开头或结尾找到匹配项, 一个空字符串包含在开头或结尾 返回数组。

但您可以使用.Where(s =&gt; !string.IsNullOrEmpty(s)) 或类似的方式轻松删除它。

【讨论】:

  • @Nofuzy 我根据您更新的问题更新了我的答案
  • 您更新的答案将生成一个字符串,但我需要一个分隔字符串的列表。如何解决?
  • @Nofuzy 也许你可以使用Regex.Split(yourString, @"(?=separators)") - 根据康拉德克拉克的评论,separatorsString.Join(collections[index], "|")。然后,您需要遍历数组以将匹配的字符串替换为其各自的值。明天我将编辑我的答案以包含该内容
  • @Nofuzy 很高兴,但我不太愿意将我的邮件分发给所有人,因为我已经收到了足够多的垃圾邮件,所以如果你有办法我可以给你,那么很好
【解决方案2】:

您可以使用SelectMany linq 函数来展平列表。这个新的字符串列表可以提供给Split 函数。

var str = "You ask your questions on StackOverFlow.com";
var collections = new[]
{
    new List<string> { "You", "your" },
    new List<string> { "Stack", "Flow" },
};

var values = str.Split(
    collections.SelectMany(s => s).Distinct().ToArray(), 
    StringSplitOptions.RemoveEmptyEntries
);

Console.WriteLine(
    string.Join(", ", values)
);

上面的代码导致

在 、Over、.com 上提问、提问

【讨论】:

  • 你不应该用更多的问题来更新你的问题,如果你想扩展你的问题,你应该创建一个新的问题。现在所有现有答案都无效...
【解决方案3】:

您可以使用 linq 展平您的收藏:

var collections = new[]{
    new List<string> { "You", "your" },
    new List<string> { "Stack", "Flow" },
};

var target = "You ask your questions on StackOverFlow.com";

var splitparts = collections.SelectMany(list => list.Select(s => s)).Distinct().ToArray();

var result = target.Split(splitparts,StringSplitOptions.RemoveEmptyEntries);

这会导致想要的

" ask ", " questions on ", "Over", ".com"

Distinct() 部分从您的收藏中删除重复项。

【讨论】:

    【解决方案4】:

    But do not know how to check an entire collection of lists.

    我对您的问题的解读是,您在“集合集合”方面遇到了问题。当其他人展示如何将列表集合压缩为单个列表时,能够搜索嵌套集合是一项非常有用的技能。我本着这种精神提出这个。

            var myString = "You ask your questions on StackOverFlow.com";
    
            var collections = new[]
            {
                new List<string> { "You", "your" },
                new List<string> { "Stack", "Flow" },
            };
    
            foreach (var listOfStrings in collections)
            {
                foreach (var word in listOfStrings)
                {
                    Console.WriteLine(myString.Contains(word) ? "Yes on " + word : "No on " + word);
                }
            }
    

    我只是在匹配时输出“是”或“否”,但您可以将它们从字符串中删除,或者用其他字符串替换它们,或者进行任何您想做的转换。我最感兴趣的是根据您的问题的措辞展示如何遍历 List 的 collection[]。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-29
      • 2015-07-12
      • 2021-06-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多