I am trying to make a function that lists all properties of an object
showProps = (obj) ->
result = ""
result+= String(i+ ' = ' + obj[i] + '\n') for i in obj when obj.hasOwnProperty(i)
return result
O = {A:1}
alert showProps O
Why does the function return nothing?
CoffeeScript's for...in loops are for looping over arrays. To iterate over an object, you want for...of (which compiles to Javascript's for...in).
If you use
result+= String(i+ ' = ' + obj[i] + '\n') for i of obj when obj.hasOwnProperty(i)
then you will get the result you're looking for.
As #muistooshort pointed out, you can get the hasOwnProperty part for free in CoffeeScript with own, which makes the code a bit simpler:
result+= String(i+ ' = ' + obj[i] + '\n') for own i of obj
You want an for [own] of-loop to iterate over properties:
showProps = (obj) ->
result = ""
result+= String(i+ ' = ' + v + '\n') for own i, v of obj
return result
O = {A:1}
alert showProps O
Btw, you don't need the explicit String call since you're concatenating strings anyway, and your whole function could be defined more easily as an array comprehension:
showProps = (obj) ->
(i+' = '+v for own i, v of obj).join('\n')
It doesn't work because you used wrong operator. in is meant to be used for iterating through collections, like an array for example. You would like to use of operator.
Besides I changed your example a bit to make it more CoffeeScript way:
showProps = (obj) ->
result = ""
result += "#{i} = #{v} \n" for i, v of obj when obj.hasOwnProperty(i)
result
anObject = A:1
alert showProps anObject
Related
I'm trying to use "_" in Case but I'm missing some thing.
What i'm doing is :
case (Packet =:= #xmlel{name = <<"message">>, attrs = [_, {<<"type">>,<<"chat">>}], children = _}) of
true ->
?INFO_MSG("True ###### Packet ~p", [Packet]);
_ ->
?INFO_MSG("False ###### Packet ~p", [Packet])
end,
And the error is : variable '_' is unbound.
I want this variable "_" to mean in this function every thing.
Like -->
attrs = [Whatever, {<<"type">>,<<"chat">>}]
children = Whatever
How can I do it? thnx.
The problem is:
You cannot use '_' on the right of '='
You can only put it on the left of the '='
e.g.
{_,4} = {x,y} (correct)
{x,y} = {_,4} (wrong)
I'm trying to understand what's going on in this recursive function. It reverses a String, but I don't quite get how these separate return calls get assembled into one string at the end.
def reverse(string: String): String = {
if (string.length() == 0)
return string
return reverse(string.substring(1)) + string.charAt(0)
}
I've analysed the function by adding in print statement, and while I kind of understand how it works (conceptually), I don't understand, well... how it works.
For instance, I know that each cycle of recursion pushes things into the stack.
So, I would expect reverse("hello"), to become a stack of
o
l
l
e
h
But it must be more complex than that, as the recursive call is return reverse(string.substring(1)) + string.charAt(0). So is the stack actually
o,
l, o
l, lo
e, llo
H, ello
?
How does that get turned into the single string we expect?
The stack contains all local variables, as well as any temporary result in an expression where the recursion appears (though those are pushed on the stack even without recursion, because JVM is a stack machine) and, of course, the point where the code execution should resume on return.
In this case, the recursive call is the whole expression (that is, nothing is computed before reverse on the expression it appears). So the only thing besides the code pointer is string. At the deepest level of recursion, the stack will look like this:
level string
5 (empty string)
4 o
3 lo
2 llo
1 ello
0 hello
So when the call to level 5 returns, level 4 will finish computing the expression that reverse is a part of, reverse(string.substring(1)) + string.charAt(0). The value of reverse(string.substring(1)) is the empty string, and the value of string.charAt(0) is o (since the value of string on level 4 is o). The result is o, which is returned.
On level 3, it concatenates the return value from level 4 (o) with string.charAt(0) for string equal to lo, which is l, resulting in ol.
On level 2, it concatenates ol with l, giving oll.
Level 1 concatenates oll with e, returning olle.
Level 0, finally, concatenates olle with h, returning olleh to its caller.
On a final note, when a call is made, what is pushed into the stack is the return point for the code and the parameters. So hello is the parameter to reverse, which is pushed on the stack by reverse's caller.
Use the substitution model to work through the problem:
reverse("hello") =
(reverse("ello") + 'h') =
((reverse("llo") + 'e') + 'h') =
(((reverse("lo") + 'l') + 'e') + 'h') =
((((reverse("o") + 'l') + 'l') + 'e') + 'h') =
(((((reverse("") + 'o') + 'l') + 'l') + 'e') + 'h') =
((((("" + 'o') + 'l') + 'l') + 'e') + 'h') =
(((("o" + 'l') + 'l') + 'e') + 'h') =
((("ol" + 'l') + 'e') + 'h') =
(("oll" + 'e') + 'h') =
("olle" + 'h') =
"olleh"
Аdd a couple of tips on how to make your code better:
Don't use return in functions because function automaticaly return result of last evaluated line
String is a List of Char's, and you can replace string.substring(1) => string.tai, and string.charAt(0) => string.head
If you call immutable method, like length, size or etc you can omit the parentheses string.length() === string.length
That last version of your single line function:
def reverse(s: String): String = if (s.size == 0) s else reverse(s.tail) + s.head
I have a function that displays a number as a properly formatted price (in USD).
var showPrice = (function() {
var commaRe = /([^,$])(\d{3})\b/;
return function(price) {
var formatted = (price < 0 ? "-" : "") + "$" + Math.abs(Number(price)).toFixed(2);
while (commaRe.test(formatted)) {
formatted = formatted.replace(commaRe, "$1,$2");
}
return formatted;
}
})();
From what I've been told, repeatedly used regexes should be stored in a variable so they are compiled only once. Assuming that's still true, how should this code be rewritten in Coffeescript?
This is the equivalent in CoffeeScript
showPrice = do ->
commaRe = /([^,$])(\d{3})\b/
(price) ->
formatted = (if price < 0 then "-" else "") + "$" + Math.abs(Number price).toFixed(2)
while commaRe.test(formatted)
formatted = formatted.replace commaRe, "$1,$2"
formatted
You can translate your JavaScript code into CoffeeScript using js2coffee. For given code the result is:
showPrice = (->
commaRe = /([^,$])(\d{3})\b/
(price) ->
formatted = ((if price < 0 then "-" else "")) + "$" + Math.abs(Number(price)).toFixed(2)
formatted = formatted.replace(commaRe, "$1,$2") while commaRe.test(formatted)
formatted
)()
My own version is:
showPrice = do ->
commaRe = /([^,$])(\d{3})\b/
(price) ->
formatted = (if price < 0 then '-' else '') + '$' +
Math.abs(Number price).toFixed(2)
while commaRe.test formatted
formatted = formatted.replace commaRe, '$1,$2'
formatted
As for repeatedly used regexes, I don't know.
I'd like to create a function My`Print[args__] that prints the names of the symbols that I pass it, along with their values. The problem is that before the symbols are passed to My`Print, they're evaluated. So My`Print never gets to see the symbol names.
One solution is to surround every argument that I pass to My`Print with Unevaluated[], but this seems messy. Is there a way of defining a MACRO such that when I type My`Print[args__], the Mathematica Kernel sees My`Print[Unevaluated /# args__]?
You need to set the attribute HoldAll on your function, with SetAttribute[my`print].
Here's a possible implementation:
Clear[my`print]
SetAttributes[my`print, HoldAll]
my`print[args__] :=
Scan[
Function[x, Print[Unevaluated[x], " = ", x], {HoldAll}],
Hold[args]
]
I used lowercase names to avoid conflicts with built-ins or functions from packages.
EDIT:
Just to make it explicit: I have two functions here. One will print the value of a single symbol, and is implemented as a Function inside. You can just use this on its own if it's sufficient. The other is the actual my`print function. Note that both need to have the HoldAll attribute.
ClearAll[My`Print]
SetAttributes[My`Print, HoldAll]
My`Print[args___] :=
Do[
Print[
Extract[Hold[args], i, HoldForm], "=", List[args][[i]]
], {i, Length[List[args]]}
]
ape = 20;
nut := 20 ape;
mouse = cat + nut;
My`Print[ape, nut, mouse]
(* ==>
ape=20
nut=400
mouse=400+cat
*)
SetAttributes[MyPrint, HoldAll];
MyPrint[var_] :=
Module[
{varname = ToString[Hold[var]]},
Print[StringTake[varname, {6, StringLength[varname] - 1}],
" = ", Evaluate[var]]
]
Coming late to the party - one can use Listability to get a rather elegant (IMO) solution avoiding explicit loops or evaluation control constructs:
ClearAll[prn];
SetAttributes[prn, {HoldAll, Listable}];
prn[arg_] := Print[HoldForm[arg], " = ", arg];
prn[args___] := prn[{args}]
Stealing the test case from #Sjoerd,
In[21]:= prn[ape,nut,mouse]
During evaluation of In[21]:= ape = 20
During evaluation of In[21]:= nut = 400
During evaluation of In[21]:= mouse = 400+cat
Out[21]= {Null,Null,Null}
Here is another variation of My`Print to add to the mix:
ClearAll[My`Print]
SetAttributes[My`Print, HoldAll]
My`Print[expr_] := Print[HoldForm[expr], " = ", expr]
My`Print[exprs___] := Scan[My`Print, Hold[exprs]]
... and another...
ClearAll[My`Print]
SetAttributes[My`Print, HoldAll]
My`Print[args___] :=
Replace[
Unevaluated # CompoundExpression # args
, a_ :> Print[HoldForm[a], " = ", a]
, {1}
]
Either way, the use is the same:
$x = 23;
f[x_] := 1 + x
My`Print[$x, $x + 1, f[1]]
(* prints:
$x = 23
$x+1 = 24
f[1] = 2
*)
In addition to the other answers consider the functions DownValues, OwnValues and UpValues:
In[1] := f[x_] := x^2
In[2] := f[x_, y_] := (x + y)^2
In[3] := DownValues[f]
Out[3] = {HoldPattern[f[x_]] :> x^2, HoldPattern[f[x_, y_]] :> (x + y)^2}
http://reference.wolfram.com/mathematica/ref/DownValues.html
I need to merge two tables, with the contents of the second overwriting contents in the first if a given item is in both. I looked but the standard libraries don't seem to offer this. Where can I get such a function?
for k,v in pairs(second_table) do first_table[k] = v end
Here's what i came up with based on Doug Currie's answer:
function tableMerge(t1, t2)
for k,v in pairs(t2) do
if type(v) == "table" then
if type(t1[k] or false) == "table" then
tableMerge(t1[k] or {}, t2[k] or {})
else
t1[k] = v
end
else
t1[k] = v
end
end
return t1
end
Wouldn't this work properly?
function merge(t1, t2)
for k, v in pairs(t2) do
if (type(v) == "table") and (type(t1[k] or false) == "table") then
merge(t1[k], t2[k])
else
t1[k] = v
end
end
return t1
end
For numeric-index table merging:
for k,v in pairs(secondTable) do table.insert(firstTable, v) end
Doug Currie's answer is the simplest for most cases. If you need more robust merging of tables, consider using the merge() method from the Penlight library.
require 'pl'
pretty.dump(tablex.merge({a=1,b=2}, {c=3,d=4}, true))
-- {
-- a = 1,
-- d = 4,
-- c = 3,
-- b = 2
-- }
Here's iterative version for deep merge because I don't like potential stack overflows of recursive.
local merge_task = {}
function merge_to_left_o(orig, new)
merge_task[orig] = new
local left = orig
while left ~= nil do
local right = merge_task[left]
for new_key, new_val in pairs(right) do
local old_val = left[new_key]
if old_val == nil then
left[new_key] = new_val
else
local old_type = type(old_val)
local new_type = type(new_val)
if (old_type == "table" and new_type == "table") then
merge_task[old_val] = new_val
else
left[new_key] = new_val
end
end
end
merge_task[left] = nil
left = next(merge_task)
end
end
I preferred James version for its simplicity and use it in my utils.lua - i did add a check for table type for error handling.
function merge(a, b)
if type(a) == 'table' and type(b) == 'table' then
for k,v in pairs(b) do if type(v)=='table' and type(a[k] or false)=='table' then merge(a[k],v) else a[k]=v end end
end
return a
end
Thanks for this nice function which should be part of the table class so you could call a:merge(b) but doing table.merge = function(a, b) ... did not work for me. Could even be compressed to a one liner for the real nerds :)
Like Doug Currie said, you can use his function, but there is a problem with his method. If first_table has things in it's k index, the function will over write it.
I'm assuming you're trying to merge these tables, not overwrite index's and value's. So this would be my method, it's very similar but is used for merging tables.
for _, v in pairs(second_table) do table.insert(first_table, v) end
The only problem with this solution is that the index is set as numbers, not as strings. This will work with tables with numbers as the index, and for tables with strings as their index, use Doug Currie's method.
Doug Currie's method:
for k,v in pairs(second_table) do first_table[k] = v end
Extending this great answer, https://stackoverflow.com/a/1283399/1570165, I would like to go with a (pure) functional approach like this one below:
-- example values
local t1 = { a = 0, b = 2 }
local t2 = { a = 1, c = 3 }
-- merge function that takes functional approach
local merge = function(a, b)
local c = {}
for k,v in pairs(a) do c[k] = v end
for k,v in pairs(b) do c[k] = v end
return c
end
-- t1 and t2 value still same after merge
print(merge(t1, t2)) -- { a = 1, b = 2, c = 3 }
print(t2) -- { a = 1, c = 3 }
print(t1) -- { a = 0, b = 2 }
for k,v in pairs(t2) do t1[k] = v end
key for string solution