我正在试图找出如何只在这里附加开头和关闭div和ul。我不知道如何将下一个字符串与ParentName的当前值进行比较:
foreach (SList subList in parentList)
{
if (subList.SubList.Count < 1)
return string.Empty;
for(int i = 0; i < subList.SubList.Count; i++)
{
if (string.Compare(subList.PName, lastPName) != 0)
{
subListItemsToHtml.AppendFormat(@"<div id='{0}-test' class='dropdown'>", subList.SubList[i].PName);
subListItemsToHtml.Append("<ul>");
}
subListItemsToHtml.AppendFormat(@" <li><a href='{0}'>{1}</a></li>", subList.SubList[i].URL, subList.SubList[i].DisplayName);
lastPName = subList.SubList[i].PName;
if (i + 1 < subList.SubList.Count)
if(string.Compare(subList.SubList[i].PName, subList.SubList[i+1].PName) != 0)
subListItemsToHtml.Append("</ul></div>");
}
}
return subListItemsToHtml.ToString();
}
答案 0 :(得分:0)
我不知道您的数据结构是否与标记的结构相匹配,但如果它匹配则更改为这似乎是合乎逻辑的:
foreach (SList subList in parentList)
{
if (subList.SubList.Count < 1)
return string.Empty;
subListItemsToHtml.AppendFormat(@"<div id='{0}-test' class='dropdown'>", subList.SubList[i].PName);
subListItemsToHtml.Append("<ul>");
for(int i = 0; i < subList.SubList.Count; i++)
{
subListItemsToHtml.AppendFormat(@" <li><a href='{0}'>{1}</a></li>", subList.SubList[i].URL, subList.SubList[i].DisplayName);
lastPName = subList.SubList[i].PName;
}
subListItemsToHtml.Append("</ul></div>");
}
return subListItemsToHtml.ToString();
就个人而言,我更倾向于使用LINQ和LINQ to XML来预测数据。这也将避免潜在的格式错误的HTML(您通过字符串连接构建HTML而无需HTML转义输出):
var xhtml = new XDocument(
new XElement("div",
from subList in parentList
where subList.SubList.Count > 0
select new XElement("div",
new XAttribute("id", subList.SubList[0].PName + "-test"),
new XAttribute("class", "dropdown"),
new XElement("ul",
from child in subList
select new XElement("li",
new XElement("a",
new XAttribute("href", child.URL),
new XText(child.DisplayName)))))));
return xhtml.ToString();
答案 1 :(得分:0)
尝试按如下方式重新编码代码:
foreach (SList subList in parentList)
{
if (subList.SubList.Count < 1)
return string.Empty;
for(int i = 0; i < subList.SubList.Count; i++)
{
if (string.Compare(subList.PName, lastPName) != 0)
{
subListItemsToHtml.AppendFormat(@"<div id='{0}-test' class='dropdown'>", subList.SubList[i].PName);
subListItemsToHtml.Append("<ul>");
subListItemsToHtml.AppendFormat(@" <li><a href='{0}'>{1}</a></li>", subList.SubList[i].URL, subList.SubList[i].DisplayName);
subListItemsToHtml.Append("</ul></div>");
}
else
{
subListItemsToHtml.AppendFormat(@" <li><a href='{0}'>{1}</a></li>", subList.SubList[i].URL, subList.SubList[i].DisplayName);
}
lastPName = subList.SubList[i].PName;
}
}
答案 2 :(得分:0)
如果有一个子列表子列表是正确的,我对你的问题不确定吗?
看起来你的结构是这样的:
public class Parent : List<SList>
{ }
public class SList
{
public List<SList> SubList = new List<SList>();
public string PName;
public string URL;
public string DisplayName;
}
在您的代码中,您将顶级子列表的PName
与每个孩子的子列表PName
进行比较,这对我来说似乎不对。也许你可以解释一下你的结构?
尽管如此,如果我认为您可以将parentList
数据展平为IEnumerable<SList>
,那么我会为您提供解决方案。
首先,我像这样展平parentList
数据:
var sublists =
from subList in parentList
from subList2 in subList.SubList
select subList2;
然后我执行以下操作:
var html = String.Join(Environment.NewLine,
sublists
.AdjacentBy(
sl => sl.PName,
sls => String.Format(@"<div id='{0}-test' class='dropdown'><ul>",
sls.First().PName),
sl => String.Format(@"<li><a href='{0}'>{1}</a></li>",
sl.URL,
sl.DisplayName),
sls => @"</ul></div>")
.SelectMany(x => x));
这会产生你的html,它应该与此相当:
var html = @"<div id='foo1a-test' class='dropdown'><ul>
<li><a href='url1a'>bar1a</a></li>
</ul></div>
<div id='goo1b-test' class='dropdown'><ul>
<li><a href='url1b'>bar1b</a></li>
<li><a href='url2a'>bar2a</a></li>
</ul></div>
<div id='foo2b-test' class='dropdown'><ul>
<li><a href='url2b'>bar2b</a></li>
</ul></div>";
现在,我确信你发现了使用新的扩展方法AdjacentBy
。这就是所有魔法发生的地方。
我非常希望将您正在进行的操作抽象为一个可重用的LINQ运算符。这样做意味着执行生成HTML工作的代码简洁明了,与迭代列表和分组结果的繁琐工作分开。
AdjacentBy
的签名如下所示:
IEnumerable<IEnumerable<V>> AdjacentBy<T, K, V>(
this IEnumerable<T> source,
Func<T, K> keySelector,
Func<IEnumerable<T>, V> headerSelector,
Func<T, V> valueSelector,
Func<IEnumerable<T>, V> footerSelector)
它的工作是在keySelector
产生的值发生变化时获取列表并列出列表。列表列表中的值来自valueSelector
。
headerSelector
&amp; footerSelector
lambdas可用于根据当前列表中的项创建页眉值和页脚值。
因此,举例来说,如果我运行此查询:
var query = "CBBCCA"
.AdjacentBy(
c => c,
cs => cs.Count().ToString() + "x",
c => c.ToString(),
cs => ".")
.ToArray();
它将相当于:
var query = new []
{
new [] { "1x", "C", "." },
new [] { "2x", "B", "B", "." },
new [] { "2x", "C", "C", "." },
new [] { "1x", "A", "." },
};
以下是AdjacentBy
的完整定义:
public static IEnumerable<IEnumerable<V>> AdjacentBy<T, K, V>(
this IEnumerable<T> source,
Func<T, K> keySelector,
Func<IEnumerable<T>, V> headerSelector,
Func<T, V> valueSelector,
Func<IEnumerable<T>, V> footerSelector)
{
var first = true;
var last = default(K);
var list = new List<T>();
var values = (IEnumerable<V>)null;
Func<List<T>, IEnumerable<V>> getValues = ts =>
{
var vs = (IEnumerable<V>)null;
if (ts.Count > 0)
{
IEnumerable<V> hs = headerSelector == null
? Enumerable.Empty<V>()
: new [] { headerSelector(ts) };
IEnumerable<V> fs = footerSelector == null
? Enumerable.Empty<V>()
: new [] { footerSelector(ts) };
vs = hs
.Concat(ts.Select(t => valueSelector(t)))
.Concat(fs)
.ToArray();
}
return vs;
};
foreach (var t in source)
{
var current = keySelector(t);
if (first || !current.Equals(last))
{
first = false;
values = getValues(list);
if (values != null)
{
yield return values;
}
list.Clear();
last = current;
}
list.Add(t);
}
values = getValues(list);
if (values != null)
{
yield return values;
}
}
我希望这会有所帮助。