-
-
Save kaareal/950383 to your computer and use it in GitHub Desktop.
var index = 0; | |
results = [], | |
prevLen; | |
while(true) { | |
r.albums[index] && results.push(r.albums[index]); | |
r.tracks[index] && results.push(r.tracks[index]); | |
r.artists[index] && results.push(r.artists[index]); | |
if(prevLen == results.length || results.length >= 9) { | |
break; | |
} | |
prevLen = results.length; | |
index++; | |
} | |
results = results.splice(0,9) |
yeah i like yours better,
var max = results.length + r.tracks.length + r.artists.lenght;
for(var i = 0; i < max || results.length <= 9; i++) {
r.albums[index] && results.push(r.albums[index]);
r.tracks[index] && results.push(r.tracks[index]);
r.artists[index] && results.push(r.artists[index]);
}
results = results.splice(0,9)
The "r.albums[index]" test will fail if any of the values encountered equates to false (0, "", false, null, undefined)
Both revised version will also run for much too long, generating an enormous result array if the input is very large. The (|| should be && in the for test)
My stab at it, tested in a browser with various values, empty arrays, etc, seems to work.
To test, just replace the ... placeholders with array initializers.
var src_a = [[...], [...], [...]]; // source arrays, each array can hold 0..∞ elements.
var out = []; // results
var rmax = Math.min(9, src_a[0].length + src_a[1].length + src_a[2].length);
for(var rx = 0; out.length < rmax; ++rx) {
var src = src_a[rx % 3]; // current source array, round-robin
var ex = Math.floor(rx / 3); // element index, js upconverts to float, so need to simulate (int) cast
if(src.length > ex) out.push(src[ex]);
}
Note that the test of the loop doesn't test rx, but the actual length of the results so far.
I think we got a winner.
I do love Arthur's code. It's very nice. That said, I'm sort of okay with the "r.albums[index]" test failing, since we are dealing with strings here (albums, artists, tracks), I don't want those falsy values in my array anyway. Kaare's second iteration for(var i = 0; i < max || results.length <= 9; i++) will keep results from getting too large or too slow.
Sorry, should be: for(var i = 0; i < max && results.length <= 9; i++). Arthur was correct.
just for shits n giggles, the C++03 version. Inline initialization of variable size arrays is a bit kludgey, a shortfall which is remedied in C++0x, whose new move semantics would also make the vector copy on return a move operation, i.e. "free." Boost also makes things more concise but I went for the basic version here.
Tested in Xcode 4.
using std::vector;
vector<int> merge3() {
int src_a[3][4] = { { 1,2 }, { 3,4,5 }, { 6,7,8,9 } };
vector<int> const va[3] = { vector<int>(src_a[0], src_a[0]+2), vector<int>(src_a[1], src_a[1]+3), vector<int>(src_a[2], src_a[2]+4) };
vector<int> results;
int rmax = std::min(9, va[0].size() + va[1].size() + va[2].size());
for(int rx = 0; results.size() < rmax; ++rx) {
vector<int> const &vsrc = va[rx % 3];
int ex = rx / 3;
if(vsrc.size() > ex) results.push_back(vsrc[ex]);
}
return results;
}
C++0x version, not completely sure about correctness, but just to show use of initializer lists, auto typing and move semantics, renamed vars for better comparison with js version, and really, save for a few parentheses and types it's the same. I'm likely the only one of us who cares about this ;)
using std::vector;
vector<int>&& merge3() {
vector<int> const src_a[3] = { { 1,2 }, { 3,4,5 }, { 6,7,8,9 } };
vector<int> out;
int rmax = std::min(9, src_a[0].size() + src_a[1].size() + src_a[2].size());
for(int rx = 0; out.size() < rmax; ++rx) {
auto src = src_a[rx % 3];
int ex = rx / 3;
if(src.size() > ex) out.push_back(src[ex]);
}
return results;
}
I like this:
r.albums[index] && results.push(r.albums[index]);
However a while(true) broken with a conditional is about WORST practice, how about this:
for(var index = 0; results.length < (r.albums.length + r.tracks.length + r.artists.length); index++) {
r.albums[index] && results.push(r.albums[index]);
r.tracks[index] && results.push(r.tracks[index]);
r.artists[index] && results.push(r.artists[index]);
}
results = results.splice(0,9);