作者:台湾金门高粱酒业集团股份公司 | 来源:互联网 | 2022-11-21 19:26
与新的.NET 6,7等一样,我们有一个列表的Except类.
List A = new List();
List B = new List();
List C = A.Except(B).ToList();
我的问题是,如何最好地进行同一类的字符串版本:
string A = "";
string B = "";
string C = A.Except(B).ToString();
获得结果= Three
相反,我得到:
System.Linq.Enumerable+d__73`1[System.Char]
我究竟做错了什么?
编辑:
只需使用最大字符串除最小字符串,反转数组顺序:
string C = B.Except(A);
和使用:尼克 new string(C.ToArray());
给了我:
hr
使用反向后略有预期的结果.
1> Ciprian Vilc..:
您的解决方案有两个问题.
ToString()的行为
在IEnumerable上执行.ToString()时,它将始终打印出类型.这是因为IEnumerable不会覆盖ToString()的行为.有关详细信息,请参阅ToString.
如果您想将IEnumerable (返回类型为Except)转换为字符串,则必须执行此操作
var C = new string(A.Except(B));
A.Except的行为(B)
Except方法不像你想象的那样工作.
以下面的代码为例:
var a = new List { 1, 2, 3 };
var b = new List { 2, 3, 4 };
var c = a.Except(b);
结果将是{1}.该方法有效地做了什么是返回a中存在但不存在于b中的所有int的新枚举.
现在,字符串只是字符的枚举 - 更准确地说,是你的字符
var A = "";
从LINQ的角度来看,相当于
var A = new List { '<', 'd', 'i', 'v', '>', ..., '<', '/', 'd', 'i', 'v', '>' };
对于B.也是
如此.当你做A.除了(B),LINQ实际上会做的是遍历每个字符并查看它是否可以在B中找到它.如果确实如此,它不会在结果中结束组.现在,由于A中的所有字符也存在于B中,因此您将获得一个空字符串.要查看实际情况,请稍微修改A,使其包含不在B中的字符:
string A = "ApplePie";
如果你现在这样做
string A = "ApplePie";
string B = "";
string C = new string(A.Except(B).ToArray());
你得到的是"AlP".
解
在我看来,做你的最好的方法是解析你的字符串,将它们转换为对象,然后做除外.没有内置算法能够告诉您的字符串是否实际构成以及如何区分它们.作为一个有效的解决方案,使用HtmlAgilityPack(一个nuget包)
var docB = new HtmlDocument();
docB.LoadHtml(B);
var docA = new HtmlDocument();
docA.LoadHtml(A);
var nodes = docB.DocumentNode.FirstChild.Descendants("p").Select(node => node.InnerHtml)
.Except(docA.DocumentNode.FirstChild.ChildNodes.Select(node => node.InnerHtml));
// take note that we are actually doing whatIsInB.Except(whatIsInA), since doing the reverse would result in nothing. There is no in A that is not also present in B
var result = string.Join(Environment.NewLine, nodes); // will resut in "Three"
var otherResult = $"
{result}
"; // "Three
"
我会让你做一个更通用的方法:)
但是这个想法是,如果你想要除了按照你期望的方式工作,你将不得不要求它使用字符串,而不是字符.
无论是否使用HtmlAgilityPack或Regex提取字符串组件所需的解析(本例中的
元素),如其他解决方案中所建议的,完全取决于您.