我读过一些博客文章提到,对于公共API,我们应该总是返回ICollection(或IEnumerable)而不是List.返回ICollection而不是List的真正优势是什么?
谢谢!
假设我需要使用动态查询过滤通用列表(List<string> l; var x = l.Where(*dynamic query*))
我如何使用LINQ做到这一点?(目前在数据视图上使用行过滤器)
我看过scott g发布的帖子:但它似乎不适用于使用的对象IEnumerable(包括通用列表)
谁能提出任何想法?
我正在学习F#,我真的很喜欢yield!(yield-bang)运算符.不仅因为它的名字,而且它当然也是它的作用.
的yield!操作者基本上可以让你产生序列的所有元素从一个序列的表达.这对于编写枚举器很有用.由于我经常遇到大而复杂的调查员,我对策略很感兴趣,我们可以用它来分解它们,并从简单的枚举器中编写它们.
不幸的是,yield!C#中没有运营商.据我了解,它的作用就像一foreach (var x in source) yield x;本书,但我正在阅读的书(Petricek的真实世界F# - Manning)表明它有更好的表现......
为了在C#中实现类似的构造,我已经探索了多种方式,但是它们都没有像yield!运算符那样简洁,我也不确定它们的复杂性.如果我的BigO号码正确,有人可以提供输入吗?
将枚举器分解为多个私有枚举器,然后从公共枚举器中生成每个元素:
foreach (var x in part1()) yield x
foreach (var x in part2()) yield x
Run Code Online (Sandbox Code Playgroud)
这将有效地导致每个元素的"双倍收益".那是O(2n)吗?(或者可能更糟?)无论如何,使用这种方法阻止我使用yield break;我的任何子部分.
将枚举器分解为多个私有枚举器,然后从公共枚举器中连接所有私有枚举器:
return part1().Concat(part2())
Run Code Online (Sandbox Code Playgroud)
我相信这与上述解决方案没有什么不同,因为它Concat()是按照我上面概述的方式实现的.
还有其他选择吗?
我有一个正确存储在List <>中的ID列表.我现在需要对此列表进行分组,并获取按降序排序的出现次数的计数.
例:
List<string> aryIDs = new List<string>;
aryIDs.Add("1234");
aryIDs.Add("4321");
aryIDs.Add("3214");
aryIDs.Add("1234");
aryIDs.Add("4321");
aryIDs.Add("1234");
Run Code Online (Sandbox Code Playgroud)
会产生:
"1234", 3
"4321", 2
"3214", 1
Run Code Online (Sandbox Code Playgroud)
这在TSQL中很容易,但我想避免服务器往返,不必要的表等,如果可能的话.
提前致谢.
更新:Ralph Shillington的VB.NET转换如下:
Dim result = From id In aryIDs _
Group id By id Into Group _
Order By Group.Count() Descending _
Select id, Count = Group.Count()
result.Dump()
Run Code Online (Sandbox Code Playgroud) 说我有一个简单的数组:
double[] myDoubleArray = new double[] { 0, 1, 2, 3, 4, 5 };
Run Code Online (Sandbox Code Playgroud)
这是性能如何:
double last = myDoubleArray.Last();
Run Code Online (Sandbox Code Playgroud)
这个?
double last = myDoubleArray[myDoubleArray.Length - 1];
Run Code Online (Sandbox Code Playgroud)
即使可以进行上述优化,Last Last()会枚举整个数组吗?
如果我传递了一些其他的IEnumerable(比如一个已经产生的),Last()必须枚举序列.我更喜欢使用Last(),因为代码看起来更干净,但如果它枚举序列我就不会做出牺牲.
我想做一个IEnumerable<TSource>可以将自己转换为a 的扩展IEnumerable<SelectListItem>.到目前为止,我一直试图这样做:
public static
IEnumerable<SelectListItem> ToSelectItemList<TSource, TKey>(this
IEnumerable<TSource> enumerable, Func<TSource, TKey> text,
Func<TSource, TKey> value)
{
List<SelectListItem> selectList = new List<SelectListItem>();
foreach (TSource model in enumerable)
selectList.Add(new SelectListItem() { Text = ?, Value = ?});
return selectList;
}
Run Code Online (Sandbox Code Playgroud)
这是正确的做法吗?如果是这样,我如何从适当的值中绘制值Func<TSource, TKey>?
我在将一个匿名对象作为参数传递给方法时遇到问题.我想像JavaScript一样传递对象.例:
function Test(obj) {
return obj.txt;
}
console.log(Test({ txt: "test"}));
Run Code Online (Sandbox Code Playgroud)
但是在C#中,它抛出了许多例外:
class Test
{
public static string TestMethod(IEnumerable<dynamic> obj)
{
return obj.txt;
}
}
Console.WriteLine(Test.TestMethod(new { txt = "test" }));
Run Code Online (Sandbox Code Playgroud)
例外:
我需要一个优雅的方法,它采用一个可枚举的方法,并获得可枚举的枚举数,每个元素中包含相同数量的元素但最后一个:
public static IEnumerable<IEnumerable<TValue>> Chunk<TValue>(this IEnumerable<TValue> values, Int32 chunkSize)
{
// TODO: code that chunks
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试过的:
public static IEnumerable<IEnumerable<TValue>> Chunk<TValue>(this IEnumerable<TValue> values, Int32 chunkSize)
{
var count = values.Count();
var numberOfFullChunks = count / chunkSize;
var lastChunkSize = count % chunkSize;
for (var chunkIndex = 0; chunkSize < numberOfFullChunks; chunkSize++)
{
yield return values.Skip(chunkSize * chunkIndex).Take(chunkSize);
}
if (lastChunkSize > 0)
{
yield return values.Skip(chunkSize * count).Take(lastChunkSize);
}
}
Run Code Online (Sandbox Code Playgroud)
(对不起,很长的帖子,直接跳到问题,见底部)
(更新:如果您正在重新访问,请参阅标记为"更新"的部分;)
我让自己更好地了解F#序列引擎盖下发生了什么.我需要优化的任务包括将字符串转换为Unicode代码点序列,我想知道是否可以在不牺牲太多性能的情况下将我们使用的可变循环替换为不可变循环.
其中一个挑战是返回的序列与输入序列的长度不同,因为代理对一起返回一个整数.这是原始代码,如下所示:
let stocp0(value: string) : seq<int> =
let pos = ref 0
seq {
while !position < value.Length do
let c = System.Char.ConvertToUtf32(value, !pos)
pos := !position + if c >= 0x10000 then 2 else 1
yield c
}
Run Code Online (Sandbox Code Playgroud)
for-do我认为最简单的方法是将其转换为for-do循环(不是for-for-do循环,它们有太多的额外开销):
let inline stocp1(value: string) =
seq {
for i = 0 to value.Length - 1 do
if(not <| Char.IsLowSurrogate(value.[i]))
then yield Char.ConvertToUtf32(value, i)
}
Run Code Online (Sandbox Code Playgroud)
这比上面的可变对应物慢了3.2倍.比我想象的更高的因素.
Seq.mapi由于字符串已经是一个序列(好的,有一个IEnumerable<char>包装器)我想用它来Seq模块中的现有序列函数,希望这可能会带来更好的性能:
let inline stocp2(value: …Run Code Online (Sandbox Code Playgroud) 作为编写流畅API的实践,我想我会进行以下编译和运行:
static void Main(string[] args)
{
Enumerable.Range(1, 100)
.When(i => i % 3 == 0).Then(i => Console.WriteLine("fizz"))
.When(i => i % 5 == 0).Then(i => Console.WriteLine("buzz"))
.Otherwise(i => Console.WriteLine(i))
.Run();
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
这个想法.When将测试枚举中的每个元素,如果它通过谓词,则运行该动作.如果谓词失败,则项目沿着链传递.
我想出的图是:
public static class EnumerableExtensions
{
public static IConditionalEnumerable<T> When<T>(this IEnumerable<T> items, Predicate<T> test, Action<T> action)
{
}
public static IResolvedEnumerable<T> Then<T>(this IConditionalEnumerable<T> items, Predicate<T> test, Action<T> action)
{
}
public static void Run<T>(this IEnumerable<T> items)
{
foreach (var item in items) ;
}
} …Run Code Online (Sandbox Code Playgroud) ienumerable ×10
c# ×7
.net ×4
linq ×4
f# ×2
anonymous ×1
arrays ×1
asp.net ×1
count ×1
dynamic ×1
enumerators ×1
icollection ×1
object ×1
performance ×1
seq ×1
sorting ×1
yield ×1