代码之家  ›  专栏  ›  技术社区  ›  cori

方法链接泛型列表扩展

  •  1
  • cori  · 技术社区  · 17 年前

    我有一个“复杂”类型的列表——一个具有一些字符串属性的对象。List本身是另一个对象的属性,包含各种类型的对象,如这个缩写的类结构所示:

    Customer {
       public List<Characteristic> Characteristics;
       .
       .
       .
    }
    
    Characteristic {
       public string CharacteristicType;
       public string CharacteristicValue;
    }
    

    我希望能够为当前客户收集给定类型特征的值列表,我可以通过以下两步过程完成:

    List<Characteristic> interestCharacteristics = customer.Characteristics.FindAll(
       delegate (Characteristic interest) {
          return interest.CharacteristicType == "Interest";
       }
    );
    
    List<string> interests = interestCharacteristics.ConvertAll<string>(
       delegate (Characteristic interest) {
          return interest.CharacteristicValue;
       }
    );
    

    这很好,但似乎还有很长的路要走。我肯定我错过了一种更简单的方法来访问这个列表,要么是将FindAll()和Convert()方法链接在一起,要么是我完全忽略的其他方法。

    作为背景,我正在工作。Net 2.0,所以我只限于。Net 2泛型,Characteristic类是一个外部依赖项——我不能改变它的结构来简化它,该类的其他方面也很重要,只是与这个问题无关。

    欢迎任何建议或补充阅读。

    3 回复  |  直到 17 年前
        1
  •  1
  •   ShuggyCoUk    17 年前

    这是一个生成器实现

    public static IEnumerable<string> GetInterests(Customer customer)
    {
        foreach (Characteristic c in customer.Characteristics)
        {
            if (c.CharacteristicType == "Interest")
                yield return c.CharacteristicValue;
        }
    }
    

    遗憾的是,根据您的需求,3.5扩展方法和lambda已经发布,但以下是操作方法:

    customer.Characteristics
        .Where(c => c.CharacteristicType == "Interest")
        .Select(c => c. CharacteristicValue);
    
        2
  •  1
  •   BFree    17 年前

    我会手工做一些工作。通过先执行FindAll,然后执行Convert,您将在集合中循环两次。这似乎没有必要。如果一天结束时你只想要一个CharacteristicValue列表,那么只需遍历你的原始集合,并将CharacteristicValue添加到符合你条件的每个集合的列表中。类似于这样:

         Predicate<Characteristic> criteria = delegate (Characteristic interest) 
         {
              return interest.CharacteristicType == "Interest";
         };
         List<string> myList = new List<string>();
         foreach(Characteristic c in customer.Characteristics)
         {
            if(criteria(c))
            {
                myList.Add(c.CharacteristicValue);
            }
         }
    
        3
  •  0
  •   Ricardo Villamil    17 年前

    为什么不创建一个 Dictionary<string, List<string>> ,这样你就可以添加“兴趣”作为键,并添加一系列值作为值。例如:

    Customer {
       public Dictionary<string, List<string>> Characteristics;
       .
       .
       .
    }
    
    ...
    
    Characteristics.Add("Interest", new List<string>());
    Characteristics["Interest"].Add("Post questions on StackOverflow");
    Characteristics["Interest"].Add("Answer questions on StackOverflow");
    ..
    
    List<Characteristic> interestCharacteristics = Characteristics["Interest"];
    

    此外,如果你愿意,你可以通过将特征设置为枚举来将其限制为一系列可能的值,然后将其用作字典键的数据类型:

    public enum CharacteristicType
    {
       Interest,
       Job,
       ThingsYouHate
    //...etc
    }
    

    然后将字典声明为:

    public Dictionary<CharacteristicType, List<string>> Characteristics;
    ..
    Characteristics.Add(CharacteristicType.Interest, new List<string>());
    Characteristics[CharacteristicType.Interest].Add("Post questions on StackOverflow");
    Characteristics[CharacteristicType.Interest].Add("Answer questions on StackOverflow");