新足迹

 找回密码
 注册

精华好帖回顾

· (第一箱油开完鸟,80.01升870km,百公里9.1升)) 我们吉普精神是在一起滴 交作业!2012grand cherokee overland CRD (2012-3-1) funday · 干烧明虾和鳗鱼叉烧饭 (2005-3-16) luxixi
· 我喜欢的TVB明星之二 - 姗姗来迟的女明星篇 (2008-6-3) 月亮 · 小儿初离家--儿子在Day Care的生活(待续) (2008-9-2) 风再起时
Advertisement
Advertisement
查看: 3265|回复: 57

[IT] 请教C# 高手之三: 寻找key value pair list object [复制链接]

发表于 2010-6-10 23:14 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
试图用hashtable, directory 来做 key value pair list, 发现都不满意。

hashtable 会自动把list sorted out by key, directory 没法去access by index.

希望有这样的list 能store a list of key value pair in original order, 能 get key by index, 能get value by key.

在Delphi里 TStringList就能轻易的实现以上的功能,C#应该也有这样的object 来实现,但我好像没发现。

谢谢指教。
持不同股见者...
Advertisement
Advertisement

发表于 2010-6-10 23:30 |显示全部楼层
此文章由 乱码 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 乱码 所有!转贴必须注明作者、出处和本声明,并保持内容完整
好像没有现成的data structure, 用两个dictionary可以轻易的实现,如果放到一个dictionary里面,从get key from value可能就要写几行code了。

发表于 2010-6-10 23:32 |显示全部楼层
此文章由 suange 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 suange 所有!转贴必须注明作者、出处和本声明,并保持内容完整
在java中,有LinkedHashMap, 它是key insertion order,应该楼主所需要的,我不懂c#,很早以前略读过c#的tutorial,觉得c#与java非常相似,不知道其中是否也有类似的data structure。

发表于 2010-6-10 23:42 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 乱码 于 2010-6-10 22:30 发表
好像没有现成的data structure, 用两个dictionary可以轻易的实现,如果放到一个dictionary里面,从get key from value可能就要写几行code了。


我查了一下google, 好像解决方案很不简单。

在Delphi里,你可以直接call TStringList.Names[index] get key, call TStringList.Values[Key] get value, 或者TStringList.IndexOfName(key) get Index.
持不同股见者...

发表于 2010-6-11 00:14 |显示全部楼层
此文章由 僚人乐土 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 僚人乐土 所有!转贴必须注明作者、出处和本声明,并保持内容完整
如果item count <= 10, 可以用 ListDictionary。
多的话,Dictionary + List —— 多一组指针而已,没必要非得在一个Type里实现吧。

[ 本帖最后由 僚人乐土 于 2010-6-10 23:23 编辑 ]

发表于 2010-6-11 00:27 |显示全部楼层
此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
你可以试下HybridDictionary
Advertisement
Advertisement

发表于 2010-6-11 00:33 |显示全部楼层
此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
NameObjectCollectionBase可能也符合你要求

2007 年度奖章获得者

发表于 2010-6-11 00:49 |显示全部楼层
此文章由 coolioo 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 coolioo 所有!转贴必须注明作者、出处和本声明,并保持内容完整
List of Dictionary 不就行了

2010年度奖章获得者

发表于 2010-6-11 01:09 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
经常会被lz的问题搞得很脑残。

在实际项目中,基本上从来没碰到过你说的情形。 如果你经常碰到的话,多半说明有更好的方法解决。

Dictionary<T, R> 倒是有时候会用一些。 Hashtable之类是给小孩子玩的吧。

绝大多数我都是用 IEnumerable<T>, IQueryable<T> + Linq

你真要专牛角尖的话,就听flyspirit 的吧。 我看了几个他的贴,思路都跟我比较接近。

发表于 2010-6-11 11:54 |显示全部楼层

回复 9# 的帖子

此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
我早已脑残了。

习惯了Delphi中的TStringList, 如果没有相似的object, 就好像有点杀鸡用牛刀。

现实的案例是这样的:

Http request, 我们要写一个response.

在程序中,我把http 的parameters 放在key/value list中,
  dictionary<string string> d = new dictionary<string string>
  d.add("ReferenceNo", "");
  d.add("SystemsID", "");
  d.add("LocationID", "");
  d.add(" PcdTo", "");
  d.add("Qty", "");

然后在得到request时做一个validation:
  string sKey  = "";
  string sValue = "";
  for (int i = 0; i < d.count; i++)
{
  sKey = d.keys;  //can't complied
  sValue = request.queryString[sKey];
  if (sValue = "")
  {
    //no parameter value
    //process error message
   break;
  }
  else
    d.values[sKey] = sValue;
//can't complied
}

在C#中,不知道用什么好的方法来解决?


[ 本帖最后由 hornsay 于 2010-6-11 10:59 编辑 ]
持不同股见者...

2010年度奖章获得者

发表于 2010-6-11 12:10 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
Use list instead of dic

then u can use foreach. And forget about index
Advertisement
Advertisement

发表于 2010-6-11 12:14 |显示全部楼层
此文章由 bigwood 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 bigwood 所有!转贴必须注明作者、出处和本声明,并保持内容完整
NameValueCollection ?

发表于 2010-6-11 12:19 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 dalaohu 于 2010-6-11 11:10 发表
Use list instead of dic

then u can use foreach. And forget about index


曾用过foreach 在dictionary上, 结果在loop 中一旦assign value to dictionary后, runtime 就出错。
持不同股见者...

发表于 2010-6-11 12:24 |显示全部楼层
此文章由 bigwood 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 bigwood 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 hornsay 于 2010-6-11 11:19 发表


曾用过foreach 在dictionary上, 结果在loop 中一旦assign value to dictionary后, runtime 就出错。



Foreach 是 read only 的, 只能用 for 来assign value

[ 本帖最后由 bigwood 于 2010-6-11 11:25 编辑 ]

发表于 2010-6-11 12:27 |显示全部楼层
此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
foreach里面是不能修改里面的值的。Validation成功后存到另外一个Collection中

发表于 2010-6-11 12:30 |显示全部楼层
此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
为什么要先初始化一个dictionary? 里面的keys是在Request里面必须有的参数吗?
Advertisement
Advertisement

发表于 2010-6-11 12:34 |显示全部楼层
此文章由 蓝爸爸 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 蓝爸爸 所有!转贴必须注明作者、出处和本声明,并保持内容完整
这种应用场合,Key的次序重要吗?用Hash应该很容易搞定你的问题的,我们有个类似的应用,PERL做的,就用Hash处理的,而且很方便检查:是否有遗漏的参数;是否有重复参数。

评分

参与人数 1积分 +2 收起 理由
hornsay + 2 感谢分享

查看全部评分

发表于 2010-6-11 12:35 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 flyspirit 于 2010-6-11 11:30 发表
为什么要先初始化一个dictionary? 里面的keys是在Request里面必须有的参数吗?



对,keys是在Request里面必须有的参数。
e.g  人家send request to www.oursteps.com.au/getsomething.aspx?ReferenceNo=refA&amp;SystemID=sysA&LocationID=locA&PcdTo=pcdA&Qty=2.
持不同股见者...

发表于 2010-6-11 12:37 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 蓝爸爸 于 2010-6-11 11:34 发表
这种应用场合,Key的次序重要吗?用Hash应该很容易搞定你的问题的,我们有个类似的应用,PERL做的,就用Hash处理的,而且很方便检查:是否有遗漏的参数;是否有重复参数。


我觉得Key的次序很user friendly, hash 会把key 重新sort out, 不够nice. 因为你一发现no value, 你马上会给出error response, 所以最好还是按次序来。

[ 本帖最后由 hornsay 于 2010-6-11 11:39 编辑 ]
持不同股见者...

发表于 2010-6-11 12:44 |显示全部楼层
此文章由 perfectstock 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 perfectstock 所有!转贴必须注明作者、出处和本声明,并保持内容完整
既然知道KEY的名字了,为什么不foreach 整个key集合呢?

            Dictionary<string, string> d=  new Dictionary<string,string>();
            
            Dictionary<string, string>.KeyCollection keyColl =   d.Keys;
            
            string sValue = null;

            foreach (string sKey in keyColl)
            {
                sValue = request.queryString[sKey];
                if (sValue == "")
                {
                    //no parameter value
                    //process error message
                    break;
                }
                else
                {
                    d[sKey] = sValue;

                }
            }

发表于 2010-6-11 12:46 |显示全部楼层
此文章由 o2h2o 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 o2h2o 所有!转贴必须注明作者、出处和本声明,并保持内容完整
OrderedDictionary
Each element is a key/value pair stored in a DictionaryEntry object. A key cannot be null, but a value can be.
The elements of an OrderedDictionary are not sorted in any way. OrderedDictionary collections allow access by both index as well as key

评分

参与人数 1积分 +2 收起 理由
hornsay + 2 感谢分享

查看全部评分

Advertisement
Advertisement

发表于 2010-6-11 12:51 |显示全部楼层

回复 18# 的帖子

此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
IList<string> keys = new List<string>(){"ReferenceNo", "SystemsID", "LocationID", "PcdTo", "Qty"};
IDictionary<string, string> result = new Dictionary<string, string>();

foreach (string key in keys)
{
    if ( Request.QueryString.Get(key) != null)
    {
        string value = Request.QueryString.Get(key);
        if ( ! String.IsNullOrEmpty(value.Trim() ) )
           result.add(key, value)
        else
           // show error
    }
    else
        // show error
}

评分

参与人数 1积分 +3 收起 理由
hornsay + 3 谢谢奉献

查看全部评分

发表于 2010-6-11 12:51 |显示全部楼层

回复 20# 的帖子

此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
d[sKey] = sValue;  run time error here.

发表于 2010-6-11 13:00 |显示全部楼层

回复 22# 的帖子

此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
看上去很好的解决方案。

发表于 2010-6-11 13:04 |显示全部楼层
此文章由 perfectstock 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 perfectstock 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 hornsay 于 2010-6-11 11:51 发表
d[sKey] = sValue;  run time error here.

Dictionary<string, string> d = new Dictionary<string, string>();
            d.Add("ReferenceNo", "");
            d.Add("SystemsID", "");
            d.Add("LocationID", "");
            d.Add("PcdTo", "");
            d.Add("Qty", "");
         
            List<string> keys = d.Keys.ToList();

            string sValue = null;

            foreach (string sKey in keys)
            {
                sValue = "Test"; //request.queryString[sKey];
                if (sValue.Length <= 0)
                {
                    //no parameter value
                    //process error message
                    break;
                }
                else
                {
                    d[sKey] = sValue;
                }
            }

发表于 2010-6-11 13:06 |显示全部楼层
此文章由 cdfei 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 cdfei 所有!转贴必须注明作者、出处和本声明,并保持内容完整
这样好像满足要求

Dictionary<string, string> d = new Dictionary<string, string>();
            
            d.Add("ReferenceNo", "1");
            d.Add("SystemsID", "2");
            d.Add("LocationID", "3");
            d.Add("cdTo", "4");
            d.Add("Qty", "");
            
           
            string sKey = "";
            string sValue = "";
            for (int i = 0; i < d.Count();i++ )
            {
                KeyValuePair<string, string> keyvalue = d.ElementAt(i);
                //can't complied
                //  sValue = request.queryString[key.Key];
                sValue = "a";
                if (string.IsNullOrEmpty(sValue))
                {
                    //no parameter value
                    //process error message
                    break;
                }
                else
                {
                    d[keyvalue.Key]=sValue;
                    

                }                    
            }
            foreach (KeyValuePair<string,string> key in d)
                MessageBox.Show(key.Value);

[ 本帖最后由 cdfei 于 2010-6-11 12:10 编辑 ]

评分

参与人数 1积分 +3 收起 理由
hornsay + 3 感谢分享

查看全部评分

Advertisement
Advertisement

发表于 2010-6-11 13:08 |显示全部楼层
此文章由 蓝爸爸 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 蓝爸爸 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 hornsay 于 2010-6-11 11:37 发表


我觉得Key的次序很user friendly, hash 会把key 重新sort out, 不够nice. 因为你一发现no value, 你马上会给出error response, 所以最好还是按次序来。


如果是为了这个,更没必要关心Key的次序了。
既然检查no value,LZ应该是把Request里所有参数都已经读到一个Hash里面了,假设叫req_hash。在读每个参数的时候,在Key Hash里面用Contains方法检查是否是不期望的参数,这个是可选的,看楼主的需要了。一旦所有参数读完了,再Key Hash上foreach一下,看req_hash是否Contains每个期望的Key。这样既检查了是否有不期望的参数(可选),又检查了每个参数是否赋值了,一旦发现no value,马上给出error response。

发表于 2010-6-11 13:15 |显示全部楼层

回复 27# 的帖子

此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
我会去试一下,因为我还没有把重复参数的validation考虑进去,你提醒了我。

发表于 2010-6-11 13:17 |显示全部楼层
此文章由 乱码 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 乱码 所有!转贴必须注明作者、出处和本声明,并保持内容完整
不是很明白lz的用意,hashtable在.net 2.0就被generic Dictionary代替了,但基本上dictionary还是用hash function,key是function的input,index是result,至于value的存放和冲突的处理,可以用不同的实现,可以是buket(enumberate一下),也可以rehash.

但对于ordereddictionary,我就不是很清楚了,没有官方的文档对他内部分析,我猜它有可能完全不用hash function,但因为key 是sorted,用到binary search是一定的,key可能是binary tree, 也可能是array, binary search对这两个data structure performance是一样的,不一样的地方就是他们占用空间不同,完全可以用不到hash的那些东西,继续叫dictionary可能是因为key/value是一个pair吧。我也不确定。

你这两个结构可以选一个用,我个人倾向于dictionary,为什么?hash function做好了可以节省空间,ordered也不错,还是有点不习惯。

我可能理解错了,到现在我还是不明白你的本意是什么,抱歉哈

发表于 2010-6-11 13:26 |显示全部楼层
此文章由 蓝爸爸 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 蓝爸爸 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 hornsay 于 2010-6-11 12:15 发表
我会去试一下,因为我还没有把重复参数的validation考虑进去,你提醒了我。


我被LZ的“先入为主"的思路给搞晕头了。其实当你在一个一个读入Request里面的参数的时候,该做的就都做了:做重复参数或者不期望参数检查,同时给Key赋值,省的后来foreach的时候为read-only头疼。也就是说,Request Hash是不需要的(除非你想保存一个原始Request参数拷贝)。等你把Request参数读完了,只需要在Key Hash上一个foreach检查是否有未赋值的参数,只要有,立即就给error response。

[ 本帖最后由 蓝爸爸 于 2010-6-11 12:27 编辑 ]

发表回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Advertisement
Advertisement
返回顶部