开发者

What function acts as .SelectMany() in jQuery?

Let me explain more:

we know that map function in jQuery acts as .Select() (as in LINQ).

$("tr").map(function() { return $(this).children().first(); }); // returns 20开发者_开发技巧 tds

now the question is how can we have .SelectMany() in jQuery?

$("tr").map(function() { return $(this).children(); }); // returns 10 arrays not 20 tds!

here is my example in action: http://jsfiddle.net/8aLFQ/4/

"l2" should be 8 if we have selectMany.

[NOTE] please don't stick to this example, above code is to just show what I mean by SelectMany() otherwise it's very easy to say $("tr").children();

Hope it's clear enough.


map will flatten native arrays. Therefore, you can write:

$("tr").map(function() { return $(this).children().get(); })

You need to call .get() to return a native array rather than a jQuery object.

This will work on regular objects as well.

var nested = [ [1], [2], [3] ];
var flattened = $(nested).map(function() { return this; });

flattened will equal [1, 2, 3].


You want this:

$("tr").map(function() { return $(this).children().get(); });

Live demo: http://jsfiddle.net/8aLFQ/12/


You're going to kick yourself:

$("tr").map(function() { return [ $(this).children() ]; }); 

It's the simple things in life you treasure. -- Fred Kwan

EDIT: Wow, that will teach me to not to test answers thoroughly.

The manual says that map flattens arrays, so I assumed that it would flatten an array-like object. Nope, you have to explicit convert it, like so:

$("tr").map(function() { return $.makeArray($(this).children()); }); 

Things should be as simple as possible, but no simpler. -- Albert Einstein


$.map expects a value (or an array of values) returned. The jQuery object you are returning is being used as a "value" instead of an "array" (which get flattened)

All you need to do is return the array of DOM elements. jQuery provides a .get() method that returns a plain array from a selection.

$("tr").map(function() { return $(this).children().get() });

Of course, I understand this is a very contrived example, since $("tr").children() does the same thing with a lot less function calls.

http://jsfiddle.net/gnarf/8aLFQ/13/


I had the same question for regular arrays, and this is the only reference I could find in StackOverflow, so I'll add the answer I came up with.

For regular arrays, you can use

Array.prototype.selectMany = function (selector) {
    return this.map(selector).reduce(function (a, b) {
        return a.concat(b);
    });
};

Thus [[1, 2], [3, 4], [5, 6, 7]].selectMany(function (a) { return a; }) evaluates to [1, 2, 3, 4, 5, 6, 7].

To use this in jQuery, you have to convert your jQuery set into an array before using it:

var result = $("tr").get().selectMany(function(a) { 
    return Array.prototype.slice.call(a.childNodes); 
});


Not sure about .selectMany() but you could change the position of .children to get the desired result.

var l2 = $("tr").children().map(function() { return $(this); }).length;

http://jsfiddle.net/8aLFQ/5/

EDIT

I think I better understand what you're after following the comments.

You can call $.makeArray(l2) to return what you are after... that is 8 objects/arrays

http://jsfiddle.net/8aLFQ/10/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜