仅当所有字段具有相同数据时才删除重复项

时间:2015-12-18 10:42:51

标签: c# if-statement duplicates code-first

只有当我的所有字段在XML中都有相同的数据时,我才需要删除重复项。但这里的问题是它不是List,而且我的字段名称也不同。 例如:

Scenario:1

<Items>-->Not a List just an generic object Type T
<Name1A>test1</Name1A>
<Book1A>booktest1</Book1A>
<Page1A>pagetest1<Page2A>
<Name2A>test2</Name2A>
<Book2A>booktest2</Book2A>
<Page2A>pagetest2</Page2A>
</Items>

在这种情况下,我必须填充以上所有字段

Scenario 2:
<Items>-->Not a List just an generic object Type T
<Name1A>test1</Name1A>
<Book1A>booktest1</Book1A>
<Page1A>pagetest1<Page2A>
<Name2A>test1</Name2A>
<Book2A>booktest1</Book2A>
<Page2A>pagetest1</Page2A>
</Items>

在这种情况下,我只需要填充<Name1A>,<Book1A>,<Page1A>,因为在下一组字段中我的数据是相同的。

Scenario 3:
<Items>-->Not a List just an generic object Type T
<Name1A>test1</Name1A>
<Book1A>booktest1</Book1A>
<Page1A>pagetest1<Page2A>
<Name2A>test2</Name2A>
<Book2A>booktest1</Book2A>
<Page2A>pagetest1</Page2A>
</Items>

在这种情况下,我也希望填充所有字段,因为<Name2A>数据不同。

1 个答案:

答案 0 :(得分:0)

您需要一个班级来代表您的项目:

class Item {

  public Item(String name, String book, String page) {
    Name = name;
    Book = book;
    Page = page;
  }

  public String Name { get; }

  public String Book { get; }

  public String Page { get; }

}

你的XML非常奇怪,你需要编写一个小的解析器。可以使用迭代器块将输入序列(XElement)转换为另一个序列(Item):

IEnumerable<Item> ParseXml(XElement root) {
  var elements = root.Elements().ToList();
  if (elements.Count%3 != 0)
    throw new ArgumentException("Number of XML child elements is not divisible by 3.");
  for (var i = 0; i < elements.Count/3; i += 1) {
    var nameElement = elements[3*i];
    ThrowIfUnexpectedElement(nameElement, "Name", i + 1);
    var bookElement = elements[3*i + 1];
    ThrowIfUnexpectedElement(bookElement, "Book", i + 1);
    var pageElement = elements[3*i + 2];
    ThrowIfUnexpectedElement(pageElement, "Page", i + 1);
    yield return new Item(
      (String) nameElement,
      (String) bookElement,
      (String) pageElement
    );
  }
}

void ThrowIfUnexpectedElement(XElement element, String prefix, Int32 index) {
  var expectedName = $"{prefix}{index}A";
  if (element.Name.LocalName != expectedName)
    throw new ArgumentException($"Unexpected XML element '{element.Name.LocalName}'. Expected '{expectedName}'.");
}

现在你可以解析XML了:

var items = ParseXml(xDocument.Root);

要删除重复项,您可以将Distinct()IEqualityComparer<Item>结合使用:

class ItemEqualityComparer : IEqualityComparer<Item> {

  public Boolean Equals(Item item1, Item item2) {
    return item1.Name == item2.Name
      && item1.Book == item2.Book
      && item1.Page == item2.Page;
  }

  public Int32 GetHashCode(Item item) {
    unchecked {
      const Int32 Multiplier = -1521134295;
      var hash = -175858345;
      hash = hash*Multiplier + item.Name.GetHashCode();
      hash = hash*Multiplier + item.Book.GetHashCode();
      hash = hash*Multiplier + item.Page.GetHashCode();
      return hash;
    }
  }

}

您可以使用以下代码获取不同的项目:

var distinctItems = items.Distinct(new ItemEqualityComparer());