如何将关联索引添加到数组。 C#

时间:2010-11-08 21:09:37

标签: c# arrays

我有一系列自定义对象。我希望能够通过特定的数据成员引用此数组,例如myArrary["Item1"]

“Item1”实际上是存储在此自定义类型的Name属性中的值,我可以编写谓词来标记相应的数组项。但是我不清楚如何让数组知道我想使用这个谓词来查找数组项。

我想对这个数组使用字典或散列表或NameValuePair,并解决整个问题,但它已生成,并且必须保持为CustomObj[]。我也试图避免从这个数组加载一个字典,因为它会多次发生,并且可能有很多对象。

澄清

myArray[5] = new CustomObj() // easy!
myArray["ItemName"] = new CustomObj(); // how to do this? 

可以做到以上几点吗?我真的只是在寻找与DataRow.Columns["MyColumnName"]的工作方式类似的东西

感谢您的建议。

9 个答案:

答案 0 :(得分:5)

你真正想要的是OrderedDictionary. .NET在System.Collections.Specialized中提供的版本不是通用的 - 但是你可以使用generic version on CodeProject 。在内部,这实际上只是一个与列表结合的哈希表...但它以统一的方式暴露。

如果您确实想要避免使用字典 - 那么您将不得不依赖于项目的O(n)查找性能。在这种情况下,坚持使用数组或列表,只需使用LINQ Where()方法来查找值。您可以使用First()Single(),具体取决于是否需要重复的条目。

var myArrayOfCustom = ...
var item = myArrayOfCustom.Where( x => x.Name = "yourSearchValue" ).First();

将此功能包装到类中非常容易,这样外部使用者就不会受到这些知识的负担,并且可以使用简单的索引器来访问数据。如果您希望经常访问相同的值,则可以添加memoization等功能。通过这种方式,您可以分摊通过多次访问构建基础查找字典的成本。

答案 1 :(得分:2)

如果您不想使用“Dictionary”,那么您应该创建具有数据大容量存储功能的类“myArrary”,并为索引访问添加类型为“int”的索引器,并为关联访问添加“string”类型的索引器。 p>

public CustomObj this [string index]
{
    get
    {
        return data[searchIdxByName(index)];
    }
    set
    {
        data[searchIdxByName(index)] = value;
    }
}

谷歌索引器的第一个链接是:http://www.csharphelp.com/2006/04/c-indexers/

答案 2 :(得分:0)

你可以使用字典,虽然它可能不是世界上最好的解决方案,但这是我提出的第一个。

    Dictionary<string, int> d = new Dictionary<string, int>();
    d.Add("cat", 2);
    d.Add("dog", 1);
    d.Add("llama", 0);
    d.Add("iguana", -1);

整体可能是对象,你喜欢什么:)

http://dotnetperls.com/dictionary-keys

答案 3 :(得分:0)

或许OrderedDictionary正是您所寻找的。

答案 4 :(得分:0)

你可以使用HashTable;

System.Collections.Hashtable o_Hash_Table = new Hashtable();
o_Hash_Table.Add("Key", "Value");

答案 5 :(得分:0)

您应该使用名为System.Collections的{​​{1}}命名空间中的一个类。

Dictionary<K,V>

另一种方法是编写两个方法/属性:

var d = new Dictionary<string, MyObj>();
MyObj o = d["a string variable"];

我希望它有所帮助!

答案 6 :(得分:0)

这取决于集合,有些集合允许按名称访问,有些则不允许。只有当集合存储了数据时,才能使用字符串进行访问,列集合按名称标识列,从而允许您按名称选择列。在普通数组中,这不起作用,因为项目仅由其索引号标识。

答案 7 :(得分:0)

我最好的建议是,如果你不能改变它来使用字典,那就是使用Linq表达式:

var item1 = myArray.Where(x => x.Name == "Item1").FirstOrDefault();

或者,创建一个使用linq表达式的扩展方法:

public static class CustomObjExtensions
{
    public static CustomObj Get(this CustomObj[] Array, string Name)
    {
        Array.Where(x => x.Name == Name).FirstOrDefault();
    }
}

然后在你的应用中:

var item2 = myArray.Get("Item2");

但请注意,性能不如使用字典那么好,因为在幕后.NET只会循环遍历列表,直到找到匹配为止,所以如果你的列表不会经常更改,那么你可以改为制作一本词典。

答案 8 :(得分:0)

我有两个想法:

1)我不确定你是否知道但是你可以将字典对象复制到这样的数组中:

Dictionary dict = new Dictionary();
dict.Add("tesT",40);
int[] myints = new int[dict.Count];
dict.Values.CopyTo(myints, 0);

这可能允许您对所有内容使用Dictionary,同时仍将输出保持为数组。

2)如果这是您想要的确切功能,您还可以通过编程方式实际创建DataTable:

DataTable dt = new DataTable();
DataColumn dc1 = new DataColumn("ID", typeof(int));
DataColumn dc2 = new DataColumn("Name", typeof(string));
dt.Columns.Add(dc1);
dt.Columns.Add(dc2);
DataRow row = dt.NewRow();
row["ID"] = 100;
row["Name"] = "Test";
dt.Rows.Add(row);

您也可以在方法之外创建此方法,这样您就不必每次都重新制作表格。