2012-12-06 4 views
0

저는 이것에 대해 앞뒤로 논합니다. 나는 Hashtable (또는 사전 ... 둘 다이 목적을 위해 좋은 것처럼 보이는 것)을 가지고 싶다.내 해시 테이블 값에 키가 포함되어야합니까?

나는 ItemNumber, Description, and Quantity를 가진 클래스 Item을 가지고있다. 나는 해시 테이블이나 사전을 사용하고자하는 ItemCollection 클래스 (현재 Item 배열을 사용하고있다)를 가지고있다. 내 Item 클래스에서 ItemNumber를 사용하여 item a == item인지 비교합니다. b.

그래서 ItemNumber를 ItemCollection의 키로 매핑해야합니다. 그렇지 않으면 그냥 그대로 두어야합니다. 나 부분은 Item을 기반으로 테이블을 생성하기 때문에 남겨두고 싶다. 그러나 내 생각에 또 다른 부분은 그것이 중복되고 바보 같다고 생각한다.

출하 품목 인 ItemCollection이 이와 같이 처리하여 다른 ItemCollection (주문)과 동일한 지 확인하는 것이 최종 목표는 무엇입니까?

foreach(var package in shipments) 
    foreach(var item in package) 
     shipOrder += item; 

return mainOrder==shipOrder; 

이 정보가 도움이되기를 바랍니다. 내 머리가 아프기 때문에 조금 안개가 낀다. 그래서 나는 좀 더 명확히 할 필요가있다.

편집 나는 모든 사람들이 한 말에 대해 생각하고 그것을 시도 및 테스트의 대부분을 제외한 통과하고 난 이유를 알아낼 수

확인. 그래서 내가 가지고있는 것을 게시하고, 너희들이 내 바보 같은 실수를 알아낼 수 있는지 보겠다.

public class Item 
{ 
    public Item(object[] array) 
    { 
     ItemNumber = array[0].ToString(); 
     Description = array[1].ToString(); 
     Quantity = (int)array[2]; 
    } 
    public Item(string item, string desc, int qty) 
    { 
     ItemNumber = item; 
     Description = desc; 
     Quantity = qty; 
    } 
    /// <summary> 
    /// </summary> 
    public string ItemNumber; 
    public string Description; 
    public int Quantity; 

    public override bool Equals(object obj) 
    { 
     //return compareTwoItems(this, (Item)obj); 
     return this.GetHashCode() == obj.GetHashCode(); 
    } 
    public static bool operator ==(Item ic1, Item ic2) 
    { 
     return compareTwoItems(ic1, ic2); 
    } 
    public static bool operator !=(Item ic1, Item ic2) 
    { 
     return !compareTwoItems(ic1, ic2); 
    } 
    private static bool compareTwoItems(Item ic1, Item ic2) 
    { 
     return (ic1.ItemNumber == ic2.ItemNumber) 
      && (ic1.Quantity == ic2.Quantity); 
    } 
    public override int GetHashCode() 
    { 
     return ItemNumber.GetHashCode()^Quantity; 
    } 
} 
public class ItemCollection : System.Collections.Generic.SortedDictionary<string, Item> 
{ 
    public ItemCollection() 
    { 
    } 
    public void AddItem(Item i) 
    { 
     this.Add(i.ItemNumber, i); 
    } 

    public string TrackNumber = ""; 
    /// <summary> 
    /// Check to see if the Two ItemCollections have the same Quantity of items. If not it may be that the order was not completed 
    /// </summary> 
    /// <param name="obj">the sales order items</param> 
    /// <returns>True if the quantity of the two collections are the same.</returns> 
    /// <exception cref="ArgumentException">If the collections have different counts, or if ItemNumbers differ in one of the elements</exception> 
    public override bool Equals(object obj) 
    { 
     return this.GetHashCode() == ((ItemCollection)obj).GetHashCode(); 
    } 
    public override int GetHashCode() 
    { 
     int hash = 0; 
     foreach (var item in this.Values) 
      hash ^= item.GetHashCode(); 

     return hash; 
    } 
    /// <summary> 
    /// Check to see if the Two ItemCollections have the same Quantity of items. If not it may be that the order was not completed 
    /// </summary> 
    /// <param name="ic1">the sales order items</param> 
    /// <param name="ic2">the shipping ticket items</param> 
    /// <returns>True if the quantity of the two collections are the same.</returns> 
    /// <exception cref="ArgumentException">If the collections have different counts, or if ItemNumbers differ in one of the elements</exception> 
    public static bool operator ==(ItemCollection ic1, ItemCollection ic2) 
    { 
     return ic1.Equals(ic2); 
    } 
    public static bool operator !=(ItemCollection ic1, ItemCollection ic2) 
    { 
     return !ic1.Equals(ic2); 
    } 
} 

단위가 지금 작동 어떤 이유로 ... 내가 항목에 TEH GetHash 방법에 내 코드에서 한 가지를 변경

[TestMethod, TestCategory("ItemColl")] 
    public void ItemCollectionPassTest() 
    { 
     MSSqlDatabase db = new MSSqlDatabase(); 
     ItemCollection salesOrder = db.GetItemsCollectionFromSalesOrder(4231); 
     ItemCollection items = db.GetItemsCollectionFromSalesOrder(4231); 

     Assert.AreEqual(salesOrder, items); //passes 
     Assert.IsTrue(salesOrder == items); //passes 
    } 
    [TestMethod, TestCategory("ItemColl")] 
    public void ItemCollectionDifferentQuantity() 
    { 
     MSSqlDatabase db = new MSSqlDatabase(); 
     ItemCollection salesOrder1 = db.GetItemsCollectionFromSalesOrder(4231); 
     ItemCollection salesOrder2 = db.GetItemsCollectionFromSalesOrder(4232); 
     Assert.AreNotEqual(salesOrder1, salesOrder2); //passes 
     Assert.IsTrue(salesOrder1 != salesOrder2); //passes 

     ItemCollection[] items = db.GetItemsCollectionFromShipping(4231); 
     ItemCollection test = items[0]; 
     Assert.AreNotEqual(salesOrder1, test); //Fails 
     CollectionAssert.AreNotEqual(salesOrder1, items[0]); // passes 
    } 

.... 테스트합니다 (을에 xor하는 것을 잊었다 수량을 ItemNumber의 해시로 변환) 이제는 ... 이상하게됩니다. 하지만 어쨌든 누군가에게 도움이 될 수 있도록 코드를 게시 할 것입니다.

답변

1

, 나는 당신의 ItemCollectionDictionary 또는 Hashtable 확장한다고 생각합니다. 사전에는 각 항목에 대해 고유 한 키가 필요할 것이므로 항목 번호를 사용하십시오 (각 항목이 고유해야한다는 요구 사항 인 경우). 이처럼

:

public class Item { 
    public string ItemNumber { get; set; } 
    public string Description { get; set; } 
    public string Quantity { get; set; } 

    public override bool Equals(Object o) { 
     // Implement your Equals here 
    } 
    public override int GetHashCode() { 
     // Implement your hash code method here 
    } 
} 

public class ItemCollection : Dictionary<string, Item> { 
    public override bool Equals(Object o) { 
     // Implement your collection's Equals method here 
    } 
} 

나는 당신의 요구 사항은 컬렉션을 비교 무엇인지 확실하지 않다.

public override bool Equals(Object o) { 
    if (o == null) 
     return false; 
    if (!(o is ItemCollection)) 
     return false; 
    var other = o as ItemCollection; 

    // check the 'this' collection 
    foreach (var item in this.Keys) { 
     if (item != null && !other.ContainsKey(item.ItemNumber)) 
      return false; 

    // check the 'other' collection 
    foreach (var item in other.Keys) { 
     if (item != null && !this.ContainsKey(item.ItemNumber)) 
      return false; 
    return true; 
} 
+0

그 예를 들어 주셔서 대단히 감사합니다. 이상한 이유 때문에 단위 테스트에 실패했기 때문에 내가 가지고있는 것을 보여 드리겠습니다. –

+0

일하기 시작했기 때문에 기쁩니다. 이전에 왜 실패했는지 말할 수 없습니다. 데이터베이스에서 가져 오는 데이터에 따라 달라집니다. –

+0

예, 예상했던 것과 같이 ItemCollection과 Found ItemCollection을 말하고있었습니다. 작동하지 않아서 미쳐 가기 시작했습니다. 지금이야. –

0

당신은 기본 오브젝트 Equals()GetHashCode() 방법 오버라이드 (override) 컬렉션으로하고 항목 클래스의 HashTable<T>를 사용할 수 있습니다. 내가 scarle88에 동의

Why is it important to override GetHashCode when Equals method is overridden?

+0

내가 이미 한 그것이 문자열입니다,하지만 내 항목 번호는 숫자가 아닌 것을에 대한 메모에 : 당신은 단지 두 컬렉션이 같은 항목이 있는지 걱정한다면, 당신은이 같은 ItemCollection.Equals을 구현할 수 . (나는 그것을 좋아하지 않지만 그것이 내 통제에서 벗어났다.) 문자열을 바이트 배열과 xor 바이트 배열로 만들어야 하는가? –

+1

Item 클래스 GetHashCode 재정의에서 ItemNumber의 해시 코드 (예 : return _itemNumber)를 간단히 반환 할 수 있습니다.GetHashCode(); –

+0

얼간이가 아니어도 Item 클래스에 ItemNumber를 유지해야하는지에 대한 대답은 표시되지 않습니다. 다른 부분은 의미가 있으며 느린 질문에 대한 답을 얻었습니다. –