首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >String.Except类List.Except的快速实现方法

String.Except类List.Except的快速实现方法
EN

Stack Overflow用户
提问于 2019-01-10 14:38:23
回答 4查看 2.1K关注 0票数 0

与新的.NET 6、7等类似,我们有一个lists类。

代码语言:javascript
复制
List<int> A = new List<int>();
List<int> B = new List<int>();
List<int> C = A.Except(B).ToList();

我的问题是,如何最好地使用同一个类的字符串版本:

代码语言:javascript
复制
string A = "<div><p>One</p><p>Two</p></div>";
string B = "<div><p>One</p><p>Two</p><p>Three</p></div>";
string C = A.Except(B).ToString();

得到结果= <p>Three</p>

相反,我得到了:

代码语言:javascript
复制
System.Linq.Enumerable+<ExceptIterator>d__73`1[System.Char]

我做错了什么?

编辑:

只需将最大的字符串用于,除了最小的字符串外,倒转数组顺序:

代码语言:javascript
复制
string C = B.Except(A);

使用:尼克氏 new string(C.ToArray());给我:

代码语言:javascript
复制
hr

在使用相反的方法后稍微没有预料到的结果。

EN

回答 4

Stack Overflow用户

发布于 2019-01-10 15:05:56

你的解决方案有两个问题。

ToString()的行为

当在.ToString()上执行IEnumerable时,它总是打印出类型。这是因为IEnumerable不覆盖ToString()的行为。有关此问题的更多信息,请参见ToString

如果要将IEnumerable (返回类型的以外)转换为字符串,则必须执行以下操作

代码语言:javascript
复制
var C = new string(A.Except(B));

A.Except(B)的行为

除了方法不像你想的那样起作用。

例如,下面的代码:

代码语言:javascript
复制
var a = new List<int> { 1, 2, 3 };
var b = new List<int> { 2, 3, 4 };
var c = a.Except(b);

其结果是{1 }。该方法有效地返回a中的所有in的新枚举,而不是b中的枚举。

现在,字符串只是字符的枚举-更准确地说,

代码语言:javascript
复制
var A = "<div><p>One</p><p>Two</p></div>";

从LINQ的角度来看,相当于

代码语言:javascript
复制
var A = new List<char> { '<', 'd', 'i', 'v', '>', ..., '<', '/', 'd', 'i', 'v', '>' };

B也是如此。

所以,当您执行A.Except( B )时,LINQ实际上要做的是遍历每个字符,看看它是否能在B中找到它。如果可以,它不会在结果集中结束。现在,由于A中的所有字符都在B中,所以您将得到一个空字符串。要了解实际情况,只需稍微修改A,使其包含一个不在B中的字符:

代码语言:javascript
复制
string A = "<div><p>One</p><p>Two</p></div>ApplePie";

如果你现在做了

代码语言:javascript
复制
string A = "<div><p>One</p><p>Two</p></div>ApplePie";
string B = "<div><p>One</p><p>Two</p><p>Three</p></div>";
string C = new string(A.Except(B).ToArray());

你会得到"AlP“。

解决方案

在我看来,执行best的最佳方法是解析字符串,将它们转换为对象,然后执行best。没有内置的算法能够分辨您的字符串实际上是结构化的,以及如何区分它们。作为一种有效的解决方案,使用HtmlAgilityPack ( nuget包)

代码语言:javascript
复制
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 &lt;p&gt; in A that is not also present in B

var result = string.Join(Environment.NewLine, nodes); // will resut in "Three"
var otherResult = $"<p>{result}</p>"; // "<p>Three</p>"

我让你做一个更一般的方法:)

但这个想法是,如果你想工作,除了你期望的方式,你将不得不要求它使用字符串,而不是字符。

是否按照其他解决方案的建议,使用HtmlAgilityPack或Regex进行字符串组件(本例中的元素)提取所需的解析,完全取决于您。

票数 5
EN

Stack Overflow用户

发布于 2019-01-10 14:43:40

使用以外()扩展方法时,返回类型是Char的列表。

文档

而且,A.Excepts(B)永远不会产生您想要的结果,因为它将字符串转换为char数组。因此,它将从B中存在的A中删除每一个字符。

你需要想一种不同的算法来做到这一点。

票数 1
EN

Stack Overflow用户

发布于 2019-01-10 14:57:09

您想要的Wnat不是Except,因为它是一个称为集合差或相对补码的集合操作,在这个操作中,您说您希望一个集合中的元素不存在于另一个集合中。

您可以使用正则表达式组实现您期望的结果:

代码语言:javascript
复制
using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
        // Input string.
        string input = "<div><p>One</p><p>Two</p><p>Three</p></div>";

        // Use named group in regular expression.
        Regex expression = new Regex(@"^<div><p>One</p><p>Two</p>(?<middle>[<>/\w]+)</div>$");

        // See if we matched.
        Match match = expression.Match(input);
        if (match.Success)
        {
            // Get group by name.
            string result = match.Groups["middle"].Value;
            Console.WriteLine("Middle: {0}", result);
        }

        // Done
        Console.ReadLine();
    }
}

使用正则表达式^<div><p>One</p><p>Two</p>(?<middle>[<>/\w]+)</div>$,您可以说字符串应该以<div><p>One</p><p>Two</p>开头(^),用</div>结束($),并且无论在包含<E 113>E 214E 115/E 216或任何字母数字字符(E 117\wE 218)之间的任何字符(E 119+E 220),都将被添加到名为E 121E<222>代码的组中。

不过,我不推荐你去尝试用regex解析HTML.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54130981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档