I need help with this function
I am trying to take in array and output a new Array that filters the old array for elements that contain certain letters. Here's what I have
the pattern is not only less typing, it executes faster without the function call and closure overhead.
if you couldn't use a regexp method (an array of objects for example), it's better to use this instead of a closure:
Code:
function filterByLetter(originalList, letter){
return originalList.filter(function(x) {return x.indexOf(this)===-1;}, letter);
}
since functions need this anyway, avoiding the extra outside closure in the looped function can help the VM execute the code body faster.
the difference is that the version above is a pure function, which is easier to optimize.
it also means we can breakup the loop code and maybe re-use it later.
the filter function is really examining something for something else, let's call it contains():
Code:
function contains(x) {return x.indexOf(this)===-1;}
function hasLetter(originalList, letter){
return originalList.filter(contains, letter);
}
function hasClass(elm, strClassName){
return contains.call( strClassName, elm.className);
}
by making the logic pure, contains() can pull double duty for the hasLetter() and hasClass() method.
we could also .filter[] an exploded classList, but i wanted to show a call example.
silly examples perhaps, but i hope to have made the point...
__________________ my site (updated 5/13) STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
As this is plainly homework here is no point in offering the OP (this is his first post here) advanced/sophisticated solutions. Teacher may be dim, but not so dim as not to suspect external help!
Code:
<script type = "text/javascript">
var names = ["AFGHANISTAN", "ALGERIA", "ARGENTINA", "BANGLADESH", "BRAZIL", "BURMA",
"CANADA", "CHINA", "COLUMBIA", "CONGO", "EGYPT", "ETHIOPIA", "FRANCE",
"GERMANY", "GHANA", "INDIA", "INDONESIA", "IRAN", "IRAQ", "ITALY",
"JAPAN", "KENYA", "MALAYSIA", "MEXICO", "MOROCCO", "NEPAL", "NIGERIA",
"NORTH KOREA", "PAKISTAN", "PERU", "PHILIPPINES", "POLAND", "RUSSIA",
"SAUDI ARABIA", "SOUTH AFRICA", "SOUTH KOREA", "SPAIN", "SUDAN", "TAIWAN",
"TANZANIA", "THAILAND", "TURKEY", "UGANDA", "UKRAINE", "UNITED KINGDOM",
"UNITED STATES", "UZBEKISTAN", "VENEZUELA", "VIETNAM", "YEMEN"];
function filterByLetter(letter) {
var letter = letter.toUpperCase();
var counter = 0;
var results = [];
for(var i=0; i<names.length; i++) {
if (names[i].indexOf(letter)>=0) { // -1 means the letter was NOT found
results[counter] = names [i];
counter ++;
}
}
var final = results.join("\n");
alert ("The letter " + letter + " was found in the following " + counter + " country names\n\n" + final)
}
filterByLetter("u");
filterByLetter(" ");
</script>
__________________
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.
As this is plainly homework here is no point in offering the OP (this is his first post here) advanced/sophisticated solutions. Teacher may be dim, but not so dim as not to suspect external help!
Obviously the student can't hand in a real world solution to the problem in this type of situation since the real world solution uses commands that haven't been taught yet.
I disagree that there is no point in offering such solutions though.
1. The particular problem is one where there is a far better solution that the one the teacher expects so the particular question being asked is not one for which the code the teacher expects to be used in the answer would normally be used. (Why can't the teachers ask questions where the code being tested is appropriate to use for the solution?) So the student will know which way to go in trying to solve similar problems in the real world after they finish their course.
2. The person asking the question (and their fellow students) are not the only people who will ever be looking for solutions to that type of problem. By providing a real world solution those who are not students who have a similar problem they need to solve will see how to do it properly.
3. Those answering the question can improve their JavaScript skills when others offer an improvement on their solution.
Admittedly none of those get the student closer to being able to provide the answer that their dim teacher expects and so it is also necessary to provide advice as to how they should go about fixing the code they ask about in the first place. With the knowledge that such a solution is a long way from being the best way to solve that particular problem and that their teacher did not present them with a problem where the code that they are supposed to know would be the appropriate way to solve it.
I disagree that there is no point in offering such solutions though.
I said "there is no point in offering the OP (this is his first post here) advanced/sophisticated solutions."
If he had only the posts in this thread previous to mine to work with, he has not advanced at all in his homework - which you seem to agree.
You are, of course, right that the more sophisticated scripts may (doubless will) be of value to others. But they do not really answer the chap's question.
As so often, I do not consider the fact that one function might execute faster than another to be of the slightest importance when that difference is not discernable. I am not a fanatic - by which I mean a person who insists on very strict standards and shows little tolerance for contrary ideas or opinions. I am a pragmatist - if it works and meets the requirement it will do fine. As Voltaire said, "The best is the enemy of the good". I do not believe in the policy "Never use 10 words where 50 will do", nor "Never use a simple tool where an elaborate one will do". I am not at all sure why your or rnd me's solutions (which are, of course, perfectly valid) are supposed to "better" or "real world". As we often say, there is more than one way to skin a cat.
While many people are still using older browsers, it is pointless to code in such a way that it works only in browsers which support HTML5. In a few year's time - perhaps.
__________________
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.
Last edited by Philip M; 12-02-2012 at 07:19 PM..
Reason: Typo
While many people are still using older browsers, it is pointless to code in such a way that it works only in browsers which support HTML5. In a few year's time - perhaps.
That comment is completely irrelevant to this particular situation as there is nothing that has been discussed here that is limited to browsers that support HTML 5. In any case support or otherwise for HTML 5 has nothing to do with JavaScript.
In the first post I made where I referenced filter() as the obvious solution to this particular problem I also included a link to a page that displays the code needed to implement it for ALL browsers that support JavaScript. So in browsers that support modern JavaScript the call would use the native filter method built into the browser and for browsers that only support antiquated JavaScript the additional code to define the filter method within the script itself would run.
Any of the posted solutions using filter will therefore work in all browsers currently in use and not just those that support the latest version of JavaScript.
Also by viewing the code needed to implement filter in browsers still using antiquated versions of JavaScript anyone can see how to implement a loop to iterate over an array so as to perform processing on each element. Even a beginner would be able to identify how to define a loop to iterate over an array from that code - which is half of the solution they need.
Also while HTML 5 is still at an early draft stage, the modern JavaScript version that includes the filter method became the official JavaScript standard back in 2011 and so filter is a standard JavaScript method.
Anyway the wording of this particular question is such that it probably originated as one intended to find out whether the person recognised that the filter method is the solution to such problems - what the problem asks you to do matches so closely to what the filter function is designed to do that it makes no sense to use the problem for anything else other than to test if the person knows about filter. Using the problem that way would make any answer that doesn't use filter wrong.
I mostly agree with you about execution speed. Readability of the code so as to make it easier to maintain is far more important and will save far more time than using more convoluted code that results in a minor speed increase. Where there are two alternatives for coding that are equally readable and where one is faster than the other then it makes sense to choose the faster alternative as the way you write your code. Where the faster version also results in shorter and more readable code then that becomes the obvious choice.
filter is a JavaScript extension to the ECMA-262 standard; as such it may not be present in other implementations of the standard.
It beats me why anyone would want to use the "workaround" filter code to cater for older browsers when the same result can be achieved in a few lines of "antiquated" Javascript code. Seems to me to be a fine example of "Never use 5 lines of code where 20 will do".
Glad you agree that readabilty of code is more important than trivial improvements in execution speed.
__________________
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.
I am not at all sure why your or rnd me's solutions (which are, of course, perfectly valid) are supposed to "better" or "real world". As we often say, there is more than one way to skin a cat.
While many people are still using older browsers, it is pointless to code in such a way that it works only in browsers which support HTML5. In a few year's time - perhaps.
1. i usually go by K.I.S.S, Occam's razor, etc. JS often rewards simple code with fast execution. i think my code is dead-simple to read: you name a function, regexp's test() method, and you name the property to test for, and it returns a new list of the list items passing your specifications. How it gets any simpler than that, i can't imagine. i don't think introducing variables where they need not be used reduces complexity. In CS terms, variables and loops adds complexity...
2. i would argue that it's certainly not pointless to the 90% of devices that my code runs upon out-of-the-box. if you wait a few years to start implementing "HTML5" (whatever that even means), you are going to get impossibly behind; we are over the hump of the roller coaster, rapidly accelerating as we descend. i'm constantly struggling to keep up, at least since this summer. when it rains, it pours.
Some of the new stuff is complicated (indexeddb, webRTC, webAudioAPI, DnD, etc), and some of it is dead-simple (localStorage, classList, dataset, cors, html5 form attribs, typedArrays, FileReader, etc). The complicated stuff is still up in the air, but at least 75% of the simple stuff is available to 75% of surfers off the shelf, and 75% of the rest can be poly-filled. that's being conservative btw.
Now that IE is live-updated, it's game over, we're circling in on virtual perfection, not spinning off on wild one-browser tangents like we were just a couple years ago. refer to caniuse; it's doesn't appear to me that much else of anything worth a $%$# is going to enter the pipe not next year, or the year after that, but 2 years? that's crazy talk. M$ may change their mind about a few things here and there, and i hope they do on RTC codecs, but most of the cats are out of the bag.
The species that thrive in the long run are not the strongest, fastest, or smartest; they are the creatures most adaptable to change.
__________________ my site (updated 5/13) STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
1. i usually go by K.I.S.S, Occam's razor, etc. JS often rewards simple code with fast execution. i think my code is dead-simple to read: you name a function, regexp's test() method, and you name the property to test for, and it returns a new list of the list items passing your specifications. How it gets any simpler than that, i can't imagine. i don't think introducing variables where they need not be used reduces complexity. In CS terms, variables and loops adds complexity...
Yes, I totally agree. But that is useless to the OP who has not learned about regular expressions yet, and can hardly submit your solution to his teacher.
Quote:
Originally Posted by rnd me
The species that thrive in the long run are not the strongest, fastest, or smartest; they are the creatures most adaptable to change.
What a lovely concept! But I fear that in that case I am doomed. I am like the Republican Senator who when he retired was asked by a reporter "I expect you have seen a lot of changes during your 40 years in the Senate". "Yes", replied the Senator, "and I was opposed to all of them".
Not true, really, but I confess that I am what the marketing guys call "a late adopter". But I am a rich late-adopter, thanks to 40 years working with computers in business environments. I remember the first 8-inch IBM floppy disk - obviously a gimmick which would not catch on.
Another way of surviving in the long-term is not to take life too seriously, not to become obsessive about anything, to retain your sense of proportion and sense of humour.
__________________
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.
filter is a JavaScript extension to the ECMA-262 standard; as such it may not be present in other implementations of the standard.
It beats me why anyone would want to use the "workaround" filter code to cater for older browsers when the same result can be achieved in a few lines of "antiquated" Javascript code. Seems to me to be a fine example of "Never use 5 lines of code where 20 will do".
filter() is is ecma 5, and every browser maker supports ecma 5.
for a small classroom example, you are probably right, there is no glaring superiority to filter() over a procedural loop. When you work on large projects, having such logic named and re-callable pays large dividends by actually lower the line count, making documentation more generic, providing a private scope so that things like setTimeout and event handler behave as expected, providing more opportunity for JITs to re-use byte-code versions of the logic, and by providing more precise error information to firebug/error consoles.
it also is nice that you can modify crucial joint in your pipes system-wide in one spot, rather than find-and-replacing 10 for loops.
lastly, i don't think it's an honest comparison to your "5 lines where 20 will do" quip. people like jQuery because "i can do XXX in on line of code!". If you run a trace on jQuery, you'll see it's actually using hundreds of lines of code over thousands of function calls to accomplish that "one line". But does/should the coder care about the work/sweat/tears that others did to build the base of his pyramid? I don't think they do, and according to the developer "it's one line", an assessment i could embrace or shun depending on the wind currents.
and let's look at the forest, not a single tree:
let's see which pattern can filter out 100 different array in less code.
__________________ my site (updated 5/13) STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
filter is a JavaScript extension to the ECMA-262 standard; as such it may not be present in other implementations of the standard.
It beats me why anyone would want to use the "workaround" filter code to cater for older browsers when the same result can be achieved in a few lines of "antiquated" Javascript code. Seems to me to be a fine example of "Never use 5 lines of code where 20 will do".
filter() is is ecma 5, and every browser maker supports ecma 5.
for a small classroom example, you are probably right, there is no glaring superiority to filter() over a procedural loop. When you work on large projects, having such logic named and re-callable pays large dividends by actually lower the line count, making documentation more generic, providing a private scope so that things like setTimeout and event handler behave as expected, providing more opportunity for JITs to re-use byte-code versions of the logic, and by providing more precise error information to firebug/error consoles.
it also is nice that you can modify crucial joint in your pipes system-wide in one spot, rather than find-and-replacing 10 for loops.
lastly, i don't think it's an honest comparison to your "5 lines where 20 will do" quip. people like jQuery because "i can do XXX in on line of code!". If you run a trace on jQuery, you'll see it's actually using hundreds of lines of code over thousands of function calls to accomplish that "one line". But does/should the coder care about the work/sweat/tears that others did to build the base of his pyramid? I don't think they do, and according to the developer "it's one line", an assessment i could embrace or shun depending on the wind currents.
and let's look at the forest, not a single tree:
let's see which pattern can filter out 100 different arrays in less code...
__________________ my site (updated 5/13) STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
Yes, I totally agree. But that is useless to the OP who has not learned about regular expressions yet, and can hardly submit your solution to his teacher.
good, F's to all cheaters who rob themselves of the opportunity to actually learn by example .
Quote:
Originally Posted by Philip M
Not true, really, but I confess that I am what the marketing guys call "a late adopter". But I am a rich late-adopter, thanks to 40 years working with computers in business environments. I remember the first 8-inch IBM floppy disk - obviously a gimmick which would not catch on.
there's hope. we used those 1kb floppys on the mini at my first job. i am not talking about anything made by apple nor something that by any means would be considered mini today; those 220v monsters were bigger than i was! it's not where you start, it's where you end up.
there's a $%@#% war going on out there, and if you decide to lean up against your rifle and rest on your laurels for some quick shut eye, well, my condolences to your next of kin. i don't want to hear about nerves; get up, get out, and fight: you're on the right side.
__________________ my site (updated 5/13) STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
there's a $%@#% war going on out there, and if you decide to lean up against your rifle and rest on your laurels for some quick shut eye, well, my condolences to your next of kin. i don't want to hear about nerves; get up, get out, and fight: you're on the right side.
I have always considered that one of the greatest advantages of my birth date is that I was too young to fight in the last war, and am too old to fight in the next.
"He who fights and runs away ......"
__________________
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.