【问题标题】:Remove redundant String from array string从数组字符串中删除多余的字符串
【发布时间】:2020-01-08 09:31:01
【问题描述】:

我想删除字符串数组中包含的现有字符串。 例如:

字符串数组包含:

string [] arra = new string[] {"Financial banking", "mobile application", "customer account opening", "financial", "banking", "mobile", "application", "account banking"};

想要的结果是:

string [] result = new string[] {"Financial banking", "mobile application", "customer account opening"}

想删除:

financial, banking, mobile, application, account banking 

因为这些字符串已经存在于字符串数组中

我试过下面的代码:

string [] arra = new string[] {"Financial banking", "mobile application", "customer account opening", "financial", "banking", "mobile", "application", "account banking"};
string [] arrb = new string[] {"Financial banking", "mobile application", "customer account opening", "financial", "banking", "mobile", "application", "account banking"};
List<string> resultarr = new List<string>();

foreach(var arralist in arra){
    foreach(var arrblist in arrb){
        if(!arralist.Contains(arrblist) && !resultarr.Contains(arrblist)){
            resultarr.Add(arrblist);
            Console.WriteLine(arrblist);
        }
    }
}

但它没有返回想要的结果。对此有任何帮助。

【问题讨论】:

  • 如果您需要添加和删除项目,那么最好将数据存储为列表等集合。如果特定功能需要,您仍然可以轻松地将其转换为数组。
  • 您的规则不清楚或至少不完整。你说“因为这些字符串已经存在于字符串数组中”,但字符串“account banking”存在于数组中。两个空格分隔的字符串都存在于数组中较早的 inside 其他字符串中,但这是一个非常显着的区别。

标签: c# arrays string


【解决方案1】:

我假设你的算法是:

  1. 将输入中的每个元素分解为单词(以空格分隔)
  2. 如果我们以前见过所有这些词(不区分大小写),则忽略该元素
  3. 否则,将该元素添加到输出中,并记住所有这些单词

这会产生您预期的输出,但可能值得在您的问题中澄清您的算法。

如果这是正确的,你可以这样做:

var input = new string[] {"Financial banking", "mobile application", "customer account opening", "financial", "banking", "mobile", "application", "account banking"};
var wordsSeen = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
var result = new List<string>();

foreach (var item in input)
{
    var words = item.Split(' ');

    // If all of the elements in 'words' are present in 'wordsSeen', ignore this item
    if (wordsSeen.IsProperSupersetOf(words))
        continue;

    result.Add(item);

    // Add all of these words to 'seen'
    wordsSeen.UnionWith(words);
}

我们使用HashSet&lt;string&gt;来记录我们看到的单词,并告诉它在单词之间进行比较时使用StringComparer.InvariantCultureIgnoreCase比较器,所以它会说两个单词是相同的,即使它们'重新使用不同的案例。 (您可能想在这里使用StringComparer.CurrentCultureIgnoreCaseStringComparer.OrdinalIgnoreCase。)

【讨论】:

  • 我要说的唯一一点是2. If we've seen ANY of those words before, ignore...。我在考虑customer account opening 存在和account 突然出现的情况。
  • @scgough 为什么?我将要求解释为“ALL”,而我的代码执行“ALL”。这个问题在这一点上还不清楚,我以一种特别的方式解释了它,说明了这一点,并针对它编写了代码。你可能不同意这个问题的解释,但这不会改变我的答案。
  • 完全理解。不挑洞。你的答案是正确的答案(我赞成)。我注意到以防万一解释应该是“任何”而不是“全部”(我就是这么读的)。
【解决方案2】:

那么Distinct 方法呢:

var result = arra.Distinct(new DistinctItemComparer()).ToArray();

但是,您可能还需要为此目的使用自定义相等比较器。

public class DistinctItemComparer : IEqualityComparer<string>
{

    public bool Equals(string x, string y)
    {
        return y.ToLower().Split().Any(c => x.ToLower().Contains(c));
    }

    public int GetHashCode(string obj)
    {
        return 1;
    }
}

在这里查看结果:

https://dotnetfiddle.net/FoC0C5

【讨论】:

    【解决方案3】:

    如果您的唯一目标是删除冗余元素。然后你可以试试这个:

    string [] arra = new string[] {"Financial banking", "mobile application", "customer account opening", "financial", "banking", "mobile", "application", "account banking"};
    var elementsToRemove = new string[]{"financial", "banking", "mobile", "application", "account banking"};
    var newArray = arra.Except(elementsToRemove).ToArray(); 
    

    您需要引入System.Ling 命名空间才能访问Except 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 2022-12-16
      • 1970-01-01
      • 2018-11-10
      • 2011-08-05
      相关资源
      最近更新 更多