Turns out the hardest part by far was just parsing the HTML in the first place. jQuery is so elegant in its simplicity and the way it builds upon itself, once I'd gotten a basic infrastructure set up that turned some HTML into an object tree, implementing selectors and each additional function took less and less time. I got the thing basically working in about a day, and with enough features to solve my problem in two.
But I digress. One of the things I implemented first was
each.
I'd never given much thought to such a thing before, but it turned out to be astoundingly simple:public CsQuery Each(Actionfunc) { foreach (DomElement obj in Elements) { func(obj); } return this; }
Usage looks like this, using lambda notation:
someObj.Each((e) => { // do stuff to e });
or using
delegate
, which is necessary if you have overloads:someObj.Each(delegate(DomObject e) { // do stuff to e });
Starting to look awfully familiar isn't it? Chaining isn't totally alien to C#, as Linq popularized the concept a while ago, and there's already a
ForEach
method on List
objects. But I can't say I've seen a lot of code that looks like this outside of jQuery. Since doing a lot of jQuery in the last year or two, though, I have come to appreciate the elegance of the syntax so much that I decided to write an extension method for general use. It's essentially identical to the above:public static IEnumerable<T> ForEach<T>(this IEnumerable<T> list, Action<T> func) { foreach (T obj in list) { func(obj); } return list; }
That's all there is to it. I used
ForEach
(instead of Each
) just to maintain consistency with the List and Array methods. Now you can use that simple syntax with any IEnumerable<T>
instead of creating standalone foreach
structures, and chain and linq and iterate to your heart's content. Once you start, I swear you won't go back...
No comments:
Post a Comment