List<T> C# 查找特定行

Posted

技术标签:

【中文标题】List<T> C# 查找特定行【英文标题】:List<T> C# find specific line 【发布时间】:2022-01-02 18:07:43 【问题描述】:

我正在阅读此https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.find?view=net-6.0 并尝试将其作为示例代码:

using System;
using System.Collections.Generic;
// Simple business object. A PartId is used to identify a part
// but the part name can change.
public class Part : IEquatable<Part>

    public string PartName  get; set; 
    public int PartId  get; set; 

    public override string ToString()
    
        return "ID: " + PartId + "   Name: " + PartName;
    
    public override bool Equals(object obj)
    
        if (obj == null) return false;
    Part objAsPart = obj as Part;
    if (objAsPart == null) return false;
    else return Equals(objAsPart);

public override int GetHashCode()

    return PartId;

public bool Equals(Part other)

    if (other == null) return false;
    return (this.PartId.Equals(other.PartId));

// Should also override == and != operators.


public class Example

public static void Main()

    // Create a list of parts.
    List<Part> parts = new List<Part>();

    // Add parts to the list.
    parts.Add(new Part()  PartName = "crank arm", PartId = 1234 );
    parts.Add(new Part()  PartName = "chain ring", PartId = 1334 );
    parts.Add(new Part()  PartName = "regular seat", PartId = 1434 );
    parts.Add(new Part()  PartName = "banana seat", PartId = 1444 );
    parts.Add(new Part()  PartName = "cassette", PartId = 1534 );
    parts.Add(new Part()  PartName = "shift lever", PartId = 1634 ); ;

    // Write out the parts in the list. This will call the overridden ToString method
    // in the Part class.
    Console.WriteLine();
    foreach (Part aPart in parts)
    
        Console.WriteLine(aPart);
    

    // Check the list for part #1734. This calls the IEquatable.Equals method
    // of the Part class, which checks the PartId for equality.
    Console.WriteLine("\nContains: Part with Id=1734: 0",
        parts.Contains(new Part  PartId = 1734, PartName = "" ));

    // Find items where name contains "seat".
    Console.WriteLine("\nFind: Part where name contains \"seat\": 0",
        parts.Find(x => x.PartName.Contains("seat")));

    // Check if an item with Id 1444 exists.
    Console.WriteLine("\nExists: Part with Id=1444: 0",
        parts.Exists(x => x.PartId == 1444));

    /*This code example produces the following output:

    ID: 1234   Name: crank arm
    ID: 1334   Name: chain ring
    ID: 1434   Name: regular seat
    ID: 1444   Name: banana seat
    ID: 1534   Name: cassette
    ID: 1634   Name: shift lever

    Contains: Part with Id=1734: False

    Find: Part where name contains "seat": ID: 1434   Name: regular seat

    Exists: Part with Id=1444: True
     */


现在我想知道是否有办法将特殊行分配到文本框或类似的东西中? 对不起,我的英语不好,我会举个例子。 在这部分代码中我们有

parts.Add(new Part()  PartName = "crank arm", PartId = 1234 );
    parts.Add(new Part()  PartName = "chain ring", PartId = 1334 );
    parts.Add(new Part()  PartName = "regular seat", PartId = 1434 );
    parts.Add(new Part()  PartName = "banana seat", PartId = 1444 );
    parts.Add(new Part()  PartName = "cassette", PartId = 1534 );
    parts.Add(new Part()  PartName = "shift lever", PartId = 1634 ); ;

现在我想将 PartName 分配到 id 为 1634 的文本框或字符串中 有人能告诉我在哪里可以买到这样的东西吗? 在这一行

      // Find items where name contains "seat".
Console.WriteLine("\nFind: Part where name contains \"seat\": 0",
    parts.Find(x => x.PartName.Contains("seat")));

它会检查partname是否包含“seat”并且输出是否存在

ID:1434 名称:普通席

问题是我不希望整个部分都有,我只想要 PartName 或 PartID,例如: “1434”,只有这个。甚至没有“ID:1434”。 我希望你们能理解我,我尽力了 :-( 再次抱歉我的英语不好。 谢谢

【问题讨论】:

【参考方案1】:

此时 Find 返回整个对象,并且默认调用 ToString() 以将其显示为字符串值。

如果您只想显示 PartId,那么您可以这样做:

Console.WriteLine("\nFind: Part where name contains \"seat\": 0",
                    parts.Find(x => x.PartName.Contains("seat"))?.PartId );

您可以改用PartNamePart 的任何其他属性

如果您想要更复杂的东西,那么您可以在 Part 类中创建一个新方法并调用它。

public class Part : IEquatable<Part>

    public string PartName  get; set; 
    public int PartId  get; set; 

    public override string ToString()
    
        return "ID: " + PartId + "   Name: " + PartName;
    

    public string AlternativeToString()
    
        return this.PartId + " " + this.PartName;
    

  //rest stays the same

然后这样称呼它

Console.WriteLine("\nFind: Part where name contains \"seat\": 0",
                    parts.Find(x => x.PartName.Contains("seat"))?.AlternativeToString() );

【讨论】:

【参考方案2】:

使用 linq:

var myPartName = parts.Where(p => p.PartId == 1432).Select(p => p.PartName).FirstOrDefault();

这将返回具有给定 ID 的第一个 partName,如果不存在,则返回 null。

您还可以考虑将列表转换为以 partId 作为键的字典,这样可以更快更轻松地查找:

var partDict = parts.ToDictionary(p => p.PartId, p => p);
var myPartName = parts[1432].PartName; // will throw if id does not exist, use TryGet for a safer version

【讨论】:

以上是关于List<T> C# 查找特定行的主要内容,如果未能解决你的问题,请参考以下文章

c#并行foreach循环查找索引

在C#中查找所有特定值的子节点

请教C#中的List<T>,筛选list中特定元素的方法

请教C#中的List<T>,删除list中特定元素的方法

List<T>.Contains() 如何查找匹配项?

在c#中的字符串列表中查找一个字符串