有没有更清洁的方法?解析和拆分列表 [英] Is there a cleaner way? Parsing and Splitting Lists

查看:115
本文介绍了有没有更清洁的方法?解析和拆分列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

>我正在为一家大型轮胎制造商进行项目,他们希望在其网站上显示下拉菜单,以帮助用户从他们提供的轮胎尺寸中进行选择.下拉菜单应类似于 www.tirerack.com [ ^ ],然后单击按尺寸轮胎".

无论如何,我知道如何编写ASP等代码,但是我的代码全是

>I am working on a project for a major tire manufacturer, and they want to put drop downs on their website to help the user pick from among the tire sizes they offer. The drop downs should be like those on www.tirerack.com[^] and then when we click "Tires by Size."

Anyway, I know how to code the ASP etc etc. But my code is all

var slashedItems = page.Options.FindAll(x => x.Contains('/') && !x.StartsWith("LT"));
            var itemsContainingX = page.Options.FindAll(x => x[2] == 'X');
            var slashedItemsWithLTInFront = page.Options.FindAll(x => x.Contains('/')
                && x.StartsWith("LT"));

            List<string> scratch1 = new List<string>(), scratch2 = new List<string>(), scratch3 = new List<string>();
            foreach (string item in slashedItems)
            {
                scratch1.Add(item.Split(new char[] { '/', 'R' })[0]);
                scratch2.Add(item.Split(new char[] { '/', 'R' })[1]);
                scratch3.Add(item.Split(new char[] { '/', 'R' })[2]);
            }

            // now remove dupes from the lists
            scratch1 = scratch1.Distinct().ToList();
            scratch2 = scratch2.Distinct().ToList();
            scratch3 = scratch3.Distinct().ToList();

            scratch1.Sort();
            scratch2.Sort();
            scratch3.Sort();

            _dropdown1List.AddRange(scratch1);
            _dropdown2List.AddRange(scratch2);
            _dropdown3List.AddRange(scratch3);


而且我必须这样做,因为如您所知,根据本指南,轮胎尺寸有几种明显不同的格式.

无论如何,必须有一种更严格的方法来编写此解析算法的代码,但我之前什么也没发生. Page.OptionsList<string>,其中包含许多轮胎尺寸条目,例如,


And I have to do this because as you know, according to this guide, tire sizes come in a few slighltly varying formats.

Anyway, there''s got to be a more tight way to code this parsing algorithm, but nothing occurs to me up front. Page.Options is a List<string> and it contains a number of tire size entries, e.g.,

155/80R13
165/65R13
165/65R14
165/80R13
175/55R15
175/65R14
175/65R15
33X12.50R15LT
345/35ZR19
8R19.5



这就是为什么我要排队



That''s why I have the lines

var slashedItems = page.Options.FindAll(x => x.Contains('/') && !x.StartsWith("LT"));
            var itemsContainingX = page.Options.FindAll(x => x[2] == 'X');
            var slashedItemsWithLTInFront = page.Options.FindAll(x => x.Contains('/')
                && x.StartsWith("LT"));



我的问题是,有没有更清洁,更紧凑的方法?

Brian



My question is, is there a cleaner and more tight way of doing it?

Brian

推荐答案

当然,有一种更干净的方法.尝试找到一个很好.
在我看来,这很明显.

首先,解析总是不好的.您需要进行合成而不是解析.

您的问题是轮胎属性和命名术语不统一.您可以将其概括.您需要创建一个数据模型,以描述模型/零件名称/编号中提到的轮胎特性的所有可能组合.现实生活中存在这些特征的某些组合,而有些则不存在.在模型的对象图顶部,您应该具有记录列表,其中引用了可能的格式,模型名称,大小等一种选择.假设您有5种不同的名称格式,4种不同的大小,7个制造商的公司,12个型号名称.您的数据模型具有每个类别的单独容器.然后,再创建一个该类的容器,该容器定义每个类别的每个项目的组合.如果某些字段为空,这不是问题.

抱歉,我无法快速为您绘制此简单内容的UML图.

内存中的对象图将不是树,而是带有循环的图.不管.有一种方法可以自动将其全部保留.使用数据合同.它可以自动将您的对象图存储在XML文件中并还原.请参阅 http://msdn.microsoft.com/en-us/library/ms733127.aspx [ ^ ],http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer .aspx [ ^ ].

现在,当您在列表中填充所有可能真正存在的轮胎时,将使用带有这些引用的类的实例容器.列表项的文本将基于格式(参考之一)和可用特征来构建.

单击列表项时,应查看这些实例的容器(例如,可以通过列表和容器中的索引找到选定的实例),并查看类实例中的所有引用.每个参考文献都会将您指向单独的特征,例如尺寸,型号等.

现在,问题已简化为手动编写XML文件的问题.请执行以下操作:对于引导程序,请对不完整的数据图示例进行编程,该示例将在内存中构建所有容器并使用DataContractSerializer将其保存.保留此临时代码以备将来使用,但不要部署它.它将为您提供XML文件的样本.数据合同文件可读性强;您将立即看到如何支持它.如果需要,您可以轻松创建更新程序-您的支持工具.

天哪,不进行解析-您无法使此类代码可靠且可支持.

—SA
Of course there is a cleaner way. It''s good that you''re trying to find one.
To me, it looks pretty obvious.

First, parsing is always bad. You need to do composing instead of parsing.

Your problem is that your tire property and naming nomenclature are non-uniform. You can generalize it. You need to create a data model which describe all possible combinations of tire characteristics mentioned in the model/part name/number. Some combinations of those characteristics exist in real life, some are not. On the top of your model''s object graph you should have the list of records which references the choice of one of possible formats, model name, size, etc. Let''s say you have 5 different name formats, 4 different sized, 7 manufacturer''s companies, 12 model names. Your data model has a separate container of each of these categories. Then, you create one more container of the class which defines a combination of each item of each category. It''s not a problem if some fields are null.

Sorry I cannot quickly draw you a UML diagram of this simple thing.

The object graph in memory won''t be a tree — it will be a graph with loops. No matter. There is a way to persist it all automatically. Use Data Contract. It can automatically store your object graphs in XML file and restore back. See http://msdn.microsoft.com/en-us/library/ms733127.aspx[^], http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx[^].

Now, when you populate a list with all possible really existing kinds of tires, you will use the container of instances of the class with those references. The text of the list item will be build based of format (one of the references) and available characteristics.

When you click on a list item, you should look at the container of those instances (you can find the selected instance by index in list and in the container, for example) and look at all the references in the class instance. Each reference will point you to the separate characteristic such as size, model number, etc.

Now, the problem is reduced to the problem of writing XML file manually. Do the following: for a bootstrap, program an incomplete sample of data graph which builds all the containers in memory and save it using the DataContractSerializer. Keep this temporary code for future use, but not deploy it. It will produce you a sample of XML file. Data Contract files are very readable; you will immediately see how to support it. If you want, you can easily create an updater — your support tool.

No parsing, for goodness sake — you cannot make such code reliable and supportable.

—SA


紧密"不一定是正确或可维护代码的良好标准.

实际上,我认为最好编写不太紧的清晰代码.

首先是描述数据的有效格式.

我不完全了解轮胎尺寸的命名法,但似乎有:

#/#R#
#/#ZR#
#X#R#
#R#

"LT"可能出现在开头或结尾.

为了非常清楚您在做什么,我将使用RegEx类创建一个描述每种格式的正则表达式,然后针对每种RegEx进行测试并使用发现的内容:

"Tight" isn''t necessarily a good criteria for correct or maintainable code.

In fact, I think it''s better to write clear code that''s less tight.

First thing is to describe the valid formats for your data.

I don''t fully understand the tire size nomenclature, but there seems to be:

# / # R #
# / # ZR #
# X # R #
# R #

with "LT" potentially appearing at the beginning or end.

To be very clear about what you are doing, I''d use the RegEx class to create a regular expression that describes each of your formats and then test against each RegEx and use the thing found:

Regex rxslash = new Regex(@"^\s*(LT)?\s*(?<n1>[0-9]+)\s*/\s*(?<n2>[[0-9]+)Z?R(?<n3>[0-9]*)\s*(LT)?\s*


"); 正则表达式rxX = ... foreach ((页中的字符串.). ){ 如果(rxslash.IsMatch(item)){ MatchCollection匹配项= rxslash.Matches(item); GroupCollection组= matchs.item( 0 ).Groups; scratch1.Add(groups [" ]); scratch2.Add(groups [" ]); scratch2.Add(groups [" ]); } 其他 if (rxX.IsMath(item)){ ... } 其他 { // 我无法识别这种格式,抛出错误或将其记录 // 以在以后修复... } }
"); Regex rxX = ... foreach (string item in page.Options) { if (rxslash.IsMatch(item)) { MatchCollection matches = rxslash.Matches(item); GroupCollection groups = matches.item(0).Groups; scratch1.Add(groups["n1"]); scratch2.Add(groups["n2"]); scratch2.Add(groups["n3"]); } else if (rxX.IsMath(item)) { ... } else { // I don't recognize this format, throw an error or log it // to fix later... } }



这绝对不是比您的代码更严格",但是它显式地处理page.Options中的每个项目.它要么分析项目,因为它与您定义的正则表达式之一匹配,要么因为项目不匹配而记录了错误. (并且您可以使用该日志来查找丢失的内容并进行修复.如果某项不在您期望的格式之一中,则当前代码将执行意外的操作.它要么全部删除,要么将其删除.最终会在其中一个下拉菜单中放入垃圾.)


此外,它还使您可以完全控制对正则表达式中匹配的不同部分的操作.

很明显,您想将#/#R#模式分成3个数字来显示,但是我不确定您要对#X#R#或#R#模式或LT或Z-也许您想将#X#放在一起,也许您想将LT放在一个单独的下拉列表中……无论您决定做什么,都有自己匹配的每个组件,并且可以完全按照自己的意愿做想要和他们在一起.



This is definitely not "tighter" than your code, but it explicitly handles each item in page.Options. It either parses the item because it matches one of the regular expressions you defined or it logs an error because the item didn''t match. (And you can use that log to find out what you missed and fix it. Your current code will do something unexpected if an item isn''t in one of the fomats you expect. It''ll either drop it entirely or it''ll end up putting garbage in one of the drop downs.)


Also it gives you complete control over what you do with the different pieces that you matched in the regular expression.

It''s pretty clear that you want to split the # / # R # pattern into 3 numbers to display, but I''m not sure what you want to do with the # X # R # or the # R # pattern or the LT or Z -- maybe you want to keep #X# together, maybe you want to put LT in a separate drop down ... Whatever you decide to do, you have each individual component that you matched and you can do exactly what you want with them.


这篇关于有没有更清洁的方法?解析和拆分列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆