底线是我想要一个linq语句,返回与下面代码相同的列表。
我觉得这是可能的,我觉得在我放弃之前我已经非常接近,并且用更多行代码拼出了我想要的东西。
虽然我会喜欢和欣赏任何能展示我未来想要实现的目标并取代我所拥有的东西的人。
public ObservableCollection<VarItem> IndexChannels
{
get
{
ObservableCollection<VarItem> filtered = new ObservableCollection<VarItem>();
filtered.Add(indexChannels.First());//add Disabled no matter what
//add the cur channels selected index if it isn't already disabled
if (!filtered.Contains(indexChannels.FirstOrDefault(i => i == CurChannel.IndexChannel)))
{
filtered.Add(indexChannels.FirstOrDefault(i => i == CurChannel.IndexChannel));
}
foreach (PdioChannelModel ch in channels)
{
//if the channels mode isn't q-decode or quad index add its Number as an index
if (ch.Mode.Value != "Q-Decode" && ch.Mode.Value != "Quad Index")
{
filtered.Add(indexChannels.FirstOrDefault(i => i.ID == ch.Number));
}
}
return filtered;
}
}
VarItem的基本结构
公共类VarItem { public int ID {get;私人集; } public string Value {get;私人集; } 公共字典MetaData {get;私人集; }
public VarItem(int id, string value)
{
this.ID = id;
this.Value = value;
MetaData = new Dictionary<string, string>();
}
示例主列表包含VarItems:
-1,“禁用”
1,“频道1”
2,“频道2”
3,“第3频道”
过滤的列表应始终包含VarItem(-1, Disabled)
。它还应包含VarItem
与ID
匹配的CurChannel.IndexChannel
,最后它应包含ID与任何VarItem
匹配的PdioChannelModel.Number
PdioChannelModel.Mode.Value != "Q-Decode" or "Quad Index"
@media screen and (max-width: 767px) {
_::-webkit-full-page-media, _:future, :root .safari_only {
padding: 10px; //or any property you need
}
}
}
如果我错过任何需要的细节,请告诉我。如果我困惑你,写了很多或需要澄清,也请告诉我。
答案 0 :(得分:0)
一种方法是生成要添加的项目列表并将其传递给构造函数。
我们肯定知道我们想要indexChannels中的第一项,并且当前频道选择索引(如果它在那里),因此该部分非常简单 - 只需new List<VarItem>
。
接下来,您要添加所有索引通道,这些通道的ID与模式不是Q-Decode或Quad Index的通道的编号相匹配。因此,为此,我使用Union
将其与第一个列表连接起来。
最后,由于FirstOrDefault
返回default(VarItem)
作为默认值,我们可以在最后删除它们,我们也可以在其中放置Distinct
以确保我们不会#39; t有重复:
get
{
return new ObservableCollection<VarItem>((
new List<VarItem>
{
indexChannels.First(),
indexChannels.FirstOrDefault(i => i == CurChannel.IndexChannel)
})
.Union(channels
.Where(ch => ch.Mode.Value != "Q-Decode" &&
ch.Mode.Value != "Quad Index")
.Select(ch => indexChannels.FirstOrDefault(i => i.ID == ch.Number)))
.Where(varItem => varItem != default(VarItem))
.Distinct());
}
仅仅为了记录,我绝不会在生产代码中这样做。调试中的任何失败都将是一个巨大的痛苦。通常,每行一行语句更易于其他人阅读,并且当一行失败时更容易调试。
答案 1 :(得分:0)
您是否关心是否在null
添加了ObservableCollection
个值?如果您要排除null
值,则FirstOrDefault
不适合在foreach
内使用。另一方面,如果您确切知道每个频道Number
属性在indexChannels
中至少存在 ,那么只需使用First
。这样一来,如果你的假设是错误的(并且Number
与任何ID
都不匹配),那么First
会抛出异常,这可能是你想要的而不是NullReferenceException
稍后将更难调试。此外,如果您确定每个频道Number
属性仅在indexChannels
中存在一次,则使用Single
,因此在违反第二个假设时会出现异常。再次,这比以后的一些意外行为更容易调试。
以下是一个示例解决方案:
return new ObservableCollection<VarItem>(
indexChannels
.Take(1)
.Union(indexChannels.Where(i => i == CurChannel.IndexChannel).Take(1))
.Union(channels
.Where(c => c.Mode.Value != "Q-Decode" &&
c.Mode.Value != "Quad Index")
// The following line could be turned into
// .Select(c => indexChannels.First(i => i.ID == c.Number))
// OR
// .Select(c => indexChannels.Single(i => i.ID == c.Number))
// OR
// .SelectMany(c => indexChannels.Where(i => i.ID == c.Number))
// depending on how many channels in indexChannels
// are expected to match each Number property.
.Select(c => indexChannels.FirstOrDefault(i => i.ID == c.Number))
);