I have the following code that obviously works but I am fairly sure there is a more terse way of expressing this in coffeescript:
todos = []
for i in [1..10]
todos.push App.store.find App.Todo, i
todos = (App.store.find(App.Todo, i) for i in [1..10])
The enclosing parentheses indicate a list comprehension, which collects the return values into an array and returns it.
Consider the two following examples. The enclosing parentheses change how Coffeescript interprets the loop.
# With parentheses (list comprehension)
todos = (App.store.find(App.Todo, i) for i in [1..10])
# Without parentheses (plain old loop)
todos = App.store.find(App.Todo, i) for i in [1..10]
And the output:
// With parentheses
todos = (function() {
var _i, _results;
_results = [];
for (i = _i = 1; _i <= 10; i = ++_i) {
_results.push(App.store.find(App.Todo, i));
}
return _results;
})();
// Without parentheses
for (i = _i = 1; _i <= 10; i = ++_i) {
todos = App.store.find(App.Todo, i);
}
Related
I want to first letter to be in upper case other in lower. But after ".", it must be upper again..
function firstToUpperCase( str ) {
return str.substr(0, 1).toUpperCase() + str.substr(1);
}
var str = 'prompt("Enter text to convert: ")
var Upcase = firstToUpperCase( str );
document.write(Upcase);
Here's a simplistic answer based on what you provided. It does not take whitespace into account following the period since you didn't mention that in the specs.
function firstToUpperCase(str) {
var parts = str.split(".");
for (i = 0; i < parts.length; i++) {
parts[i] = parts[i].substring(0, 1).toUpperCase() + parts[i].substring(1).toLowerCase();
}
return parts.join(".");
}
If you're trying to deal with sentences, something like this might be a little better, though it does not preserve exact whitespace:
function firstToUpperCase(str) {
var parts = str.split(".");
for (i = 0; i < parts.length; i++) {
sentence = parts[i].trim();
parts[i] = sentence.substring(0, 1).toUpperCase() + sentence.substring(1).toLowerCase();
}
return parts.join(". ");
For the following code:
inc = -> value = (value ? 0) + 1
dec = -> value = (value ? 0) - 1
print = -> console.log value ? 0
How can you make this work properly, so inc and dec close upon value instead of creating separate function-local variables, in the way other than explicitly assigning something to value?
In plain Javascript, you would just declare var value at outer scope:
var value;
function inc() { value = (value || 0) + 1; };
function dec() { value = (value || 0) - 1; };
function print() { console.log(value || 0); };
What is CoffeeScript way for exactly the same thing?
In CoffeeScript, the way to introduce a local variable is to assign to the variable in the appropriate scope.
This is simply the way that CoffeeScript was defined and as such is similar to Python or Ruby, which do not require a "variable declaration", except CoffeeScript also allows forward access. A side-effect is that one cannot shadow a lexical variable.
Just as with the placement of var in JavaScript, where this assignment is done (as long as it is in the correct scope) does not affect the scope of the variable.
Given
x = undefined
f = -> x
// JS
var f, x;
x = void 0;
f = function() {
return x;
};
Given
f = -> x
x = undefined
// JS
var f, x;
f = function() {
return x;
};
x = void 0;
My CoffeeScript code:
myloop = () ->
size = parseInt $('#size').val
$('#result').css 'text-align', 'center'
for i in [1..size] by 1
for j in [1..i] by 1
$('#result').append "<img src='alpha.jpg' />"
$('#result').append "<br />"
Compile into Javascript:
// Generated by CoffeeScript 1.6.3
(function() {
var myloop;
myloop = function() {
var i, j, size, _i, _j, _results;
size = parseInt($('#size').val);
$('#result').css('text-align', 'center')
_results = [];
for (i = _i = 1; _i <= size; i = _i += 1) {
for (j = _j = 1; _j <= i; j = _j += 1) {
$('#result').append("<img src='alpha.jpg' />");
}
_results.push($('#result').append("<br />"));
}
return _results;
};
}).call(this);
As my expect that _result should not be generated.
It should be $('#result').append("<br />") instead.
How can I fixed this? Thx.
Look at the docs:
Sometimes functions end with loops that are intended to run only for their side-effects. Be careful that you're not accidentally returning the results of the comprehension in these cases, by adding a meaningful return value — like true — or null, to the bottom of your function.
To "fix" your code, just add a return statement at the end of your function.
I've got this Coffeescript here:
brew = (args...) =>
for e in args
alert e
null
brew('fo', 're', 'eo');
I wish I didn't need to put null there to get it to work, but alas, that compiles to this:
brew = function() {
var args, e, _i, _len, _results;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
_results = [];
for (_i = 0, _len = args.length; _i < _len; _i++) {
e = args[_i];
alert(e);
_results.push(null);
}
return _results;
};
brew('fo', 're', 'eo');
But now I have 3 unnecessary lines:
_results = [];
_results.push(null);
return _results;
Any tips?
If you don't want a function to return anything, say so:
brew = (args...) =>
for e in args
console.log e
return
A side effect of that is that the for loop won't populate an array: CoffeeScript can guarantee that the result of the for loop expression won't be used so it won't bother calculating it. Keep in mind that everything is an expression in CoffeeScript and functions return the value of their last expression so sometimes you have to throw in explicit returns to avoid wasting time computing things that will never get used.
That CoffeeScript loop ends up like this:
for (_i = 0, _len = args.length; _i < _len; _i++) {
e = args[_i];
console.log(e);
}
Note that the explicit "return nothing" return suppresses all the _result stuff.
You can see it yourself over here.
What about this
brew = (args...) -> args.forEach alert
which compiles to
var brew,
__slice = [].slice;
brew = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return args.forEach(alert);
};
brew('fo', 're', 'eo');
I have a WCF RESTful service that returns a complex object with the following format:
{"GetMatterSearchRESTResult":{"BreakDownBypracticeGroups":[],"BreakDownByCountry":[],"TotalMatterCount":0}}.
When I have this value return, I try to access it using the following code below:
if (executor.get_responseAvailable) {
var serviceResults = executor.get_responseData();
var prasevalues = eval('(' + serviceResults + ')');
var mattersResults = prasevalues.GetMatterSearchRESTResult;
for (var a = 0; a < mattersResults.length; a++) {
alert(mattersResults[a].TotalMatterCount);
var pgBreakDown = mattersResults[a].BreakDownBypracticeGroups;
for (var b = 0; b < pgBreakDown.length; b++) {
alert(pgBreakDown[b].DepartmentName + " " + pgBreakDown[b].Count);
}
}
}
return false;
After the eval function called, i get an undefined value. Please help.
GetMatterSearchRESTResult isn't an array, it's an object, so matterResults won't have a length method. Make GetMatterSearchRESTResult an array of objects:
{"GetMatterSearchRESTResult":[{"BreakDownBypracticeGroups":[],"BreakDownByCountry":[],"TotalMatterCount":0}]}
Edit: Or, if that's not possible, you don't need to loop through the object