I have the following code and I get the error 'Duplicate Declaration query_url'.
switch(condition) {
case 'complex':
const query_url = `something`;
break;
default:
const query_url = `something`;
break;
}
I understand that query_url is getting declared twice which isn't right. But i don't know how to resolve this. Can someone please help on what should be the correct way to make this work?
Try wrapping the cases in blocks:
switch(condition) {
case 'complex': {
const query_url = `something`;
… // do something
break;
}
default: {
const query_url = `something`;
… // do something else
break;
}
}
I personally prefer (and tend to abuse) the following in these sorts of cases:
const query_url = (()=>
{
switch(condition)
case 'complex': return 'something';
default : return 'something-else';
})();
(this requires ES6 or declaring "use-strict" in Node 4.x though)
Update: Alternatively, much more compact depending on if there is any logic there or if it's a simple assignment:
const query_url = {complex : 'something'}[condition] || 'something-else';
Also, of course, depends on the amount of outside-logic embedded in those switch statements!
if you need to redeclare the same variable in each case see #Bergi 's answer bellow
if query_url can have multiple values depending on the switch branch obviously you need a variable ( declare either with var or let ).
const is set once and stays that way.
example usage with let
let query_url = '';
switch(condition) {
case 'complex':
query_url = `something`;
break;
default:
query_url = `something`;
break;
}
You can use {} to scope your switch case.
For your case, you need to return the variable as long as the var exists and is accessible between curly braces:
switch(condition) {
case 'complex': {
const query_url = `something`;
return query_url;
}
default: {
const query_url = `something`;
return query_url;
}
}
If you won't use return, you must declare a let query_url above your switch statement.
Just put your switch in a function with some return statements :
var condition;
function aSwitch(condition){
switch(condition) {
case 'complex':
return 'something';
default:
return 'something';
}
}
const query_url = aSwitch(condition);
const query_url={
complex:'something complex',
other:'other thing'
}[condition]
The drawback is,you can't have default with object,you need to have addition check of condition.
Related
I am trying to achieve the following:
Say i have an object like this:
myObj = {
john: {1: ['a', 'b',..], 2: ['aa', 'vv',...],
tom: {1: ['ab', 'bb',..], 2: ['aa', 'vv',...],
}
To achieve the above i am doing something like this which works
function (name, myNum, myList) {
let myObj = Object.assign({}, state);
// name and myNum and myList values are passed in for this eg i am
// hardcoding
let name = 'jon';
let myNum = 1;
let mylist = [1,2,3];
// I want to replace the if / else with a more elegant solution
if (myObj.hasOwnProperty(name)) {
myObj[name][myNum] = myList;
} else {
myObj[name] = {[myNum]: myList};
}
return myObj;
}
I am sure there is a much cleaner way to do this, using Object.assign or object spread.
Please advice what would be better approach.
Maybe you are looking for
myObj[name] = Object.assign(myObj[name] || {}, {[myNum]: myList});
You can also do
myObj[name] = {...myObj[name], [myNum]: myList};
but this will always create a new object.
You can also combine everything into a single expression:
function (name, myNum, myList) {
return {
...state,
[name]: {
...state[name],
[myNum]: myList,
},
};
}
I want to use the following template member function
template <typename Entity>
class SomeCollection
{
// ....
template <typename Measure, typename Filter>
Entity maximalEntity(Measure&& measure, Filter&& requirement)
{
auto maxEntity = Entity();
auto maxValue = -std::numeric_limits<double>::infinity();
for (auto ent /* some iteration method*/)
{
auto measurement = measure(ent);
if (requirement(ent) && measurement > maxValue)
std::tie(maxEntity, maxValue) = std::make_tuple { ent, measurement };
}
return maxEntity;
}
// ...
};
What is the best way to call this function from client code without Filter requirement (to just have the maximal element) ?
The best I can come up with is:
class Something;
double measure(Something&);
SomeCollection<Something> collection;
auto maximum = collection.maximalEntity(measure, [](const Something&) { return true; });
But I guess this lambda function could be improved no ?
Not sure how the lambda can be improved, but you could define a generic lambda that given any input would return always true (which could also be used here):
auto always_true = [](auto&&...) { return true; };
and you would use it as:
auto maximum = collection.maximalEntity(measure, always_true);
Live demo
An equivalent implementation for C++11 is the following:
struct always_true {
template<typename... Args>
bool operator()(Args&&...) const noexcept {
return true;
}
};
which would then be used as:
auto maximum = collection.maximalEntity(measure, always_true{});
Live demo
You could create a lambda which returns true and set it as default parameter.
auto true_filter = [](const Something& arg){ return true; };
//auto true_filter = [](auto&& arg){ return true; }; if you have c++14
...
template <typename Measure, typename Filter = decltype(true_filter)>
Entity maximalEntity(Measure&& measure, Filter requirement = true_filter)
{
...
auto maximum = collection.maximalEntity(measure);
Note the Filter has changed from Filter&&. I have not get it to work with rvalue refs here.
Though having it explicitly stated is probably better design. Just an option to have it "shorter"
C++14:
template<class T>
auto always() {
return [](auto&&...)->T{return {};};
};
or in C++11:
template<class T>
struct always {
template<class...Args>
T operator()(Args&&...)const{ return {}; }
};
use:
collection.maximalEntity(measure, always<std::true_type>());
this has the advantage that the truth of the lambda involved is encoded in the type system, which makes it marginally easier for compilers to optimize its behavior.
This also lets you do always<std::false_type> or always<std::integral_constant<int, 42>>() etc.
In C++17 I'd do:
template<auto x>
auto always() {
return [](auto&&)->std::integral_constant<decltype(x), x>
{ return {}; };
}
which permits always<true>() and always<42>() (and maybe always<nullptr>()?).
I am new to ActionScripting but I have done some Java. I was told they are kinda similar. I am coding my swf file with some AS3 integrated.
function init():void{
// do something
}
function init(var string:String):String{
// do something else
}
is this not allowed in AS? If not, is there another way of handling it besides?
Thanks in advance.
Yes, you can override functions. But the example you gave is not overriding - it's overloading. For overriding a function, you basically just create a function with the same signature and everything in a subclass and add the word "override" right before it.
You can't directly overload a function though. If you want a variable number of parameters, you have to use optional parameters instead. Like this:
function init(str:String = null):String
{
if (str == null)
{
// do one thing
return null;
}
else
{
// do another thing
return "someString";
}
}
And that's about the best you're going to be able to do in AS3. The inability to overload functions, at least strictly speaking, is a fairly common complaint and obvious shortcoming of the language.
Do you mean method overloading? Actionscript, sadly, does not support this.
To get around it, you can use default parameters, or just make your parameters a bit less constraining. This answer has some details on that.
You could try this:
function init(var string:String = "Default value"):String{
// do something
}
Actionscript does not support method overloading. However, based on the answer to this question you have other options.
If you just want to be able to accept any type, you can use * to
allow any type:
function someFunction( xx:*, yy:*, flag:Boolean = true )
{
if (xx is Number) {
...do stuff...
} else if (xx is String) {
...do stuff...
} else {
...do stuff...
}
}
If you have a large number of various parameters where order is
unimportant, use an options object:
function someFunction( options:Object )
{
if (options.foo) doFoo();
if (options.bar) doBar();
baz = options.baz || 15;
...etc...
}
If you have a variable number of parameters, you can use the ...
(rest) parameter:
function someFunction( ... args)
{
switch (args.length)
{
case 2:
arr = args[0];
someBool = args[1];
xx = arr[0];
yy = arr[1];
break;
case 3:
xx = args[0];
yy = args[1];
someBool = args[2];
break;
default:
throw ...whatever...
}
...do more stuff...
}
For cases where you need to call a common function to a number of
classes, you should specify the interface common to each class:
function foo( bar:IBazable, flag:Boolean )
{
...do stuff...
baz = bar.baz()
...do more stuff...
}
I'm creating step-by-step request for MongoDB. Everything is OK, but sort option cannot be recognized by Mongo. What I'm doing wrong?
var request = {}
request['show'] = 1;
request['category'] = category;
switch (sort) {
case "new_first":
request['sort'] = "[['time_added', -1]]";
break;
case "old_first":
request['sort'] = "[['time_added', 1]]";
break;
}
collection.find(request, function(err, posts) {
....
Thanks!
Found a solution:
sort_query = JSON.parse('{"sort":[["time_added",-1]]}')
It worked!
This AS3 function works for normal methods and getter methods:
public function MyClassTestAPI(functionName:String, ...rest):* {
var value:*;
try {
switch(rest.length) {
case 0:
value = myObj[functionName];
break;
case 1:
value = myObj[functionName].call(functionName, rest[0]);
break;
case 2:
value = myObj[functionName].call(functionName, rest[0],rest[1]);
break;
default:
throw("Cannot pass more than 2 parameters (passed " + rest.length + ")");
}
}
return value;
}
Sample usage:
this.MyClassTestAPI("Foo", "arg1"); // tests function Foo(arg1:String):String
this.MyClassTestAPI("MyProperty"); // tests function get MyProperty():String
this.MyClassTestAPI("MyProperty", "new value");// tests function set MyProperty(val:String):void
The third call does not work (throws exception).
How can I make it work for setter methods as well?
Thanks!
edit:
This is a version that works, except with getter and setter that have additional parameters.
It is ok for my needs:
public function MyClassTestAPI(functionName:String, ...rest):* {
var value:*;
try {
if (typeof(this.mediaPlayer[functionName]) == 'function') {
switch(rest.length) {
case 0:
value = myObj[functionName].call(functionName);
break;
case 1:
value = myObj[functionName].call(functionName, rest[0]);
break;
case 2:
value = myObj[functionName].call(functionName, rest[0],rest[1]);
break;
default:
throw("Cannot pass more than 2 parameters (passed " + rest.length + ")");
}
} else {
switch(rest.length) {
case 0:
value = myObj[functionName];
break;
case 1:
myObj[functionName] = rest[0];
break;
default:
throw("Cannot pass parameter to getter or more than one parameter to setter (passed " + rest.length + ")");
}
}
}
return value;
}
Setter functions works as variables, so you can't use it in this way:
myProperty.call( "new value" );
Your function for variables is pointless, because you just have to do a value assignment:
myProperty = "new value";
By the way you can include it in your function in two ways:
create a third parameter what tells your function it is a function or variable
create the value assignment in the catch section
You are currently passing only one string with value "new value"
This should do the trick:
this.MyClassTestAPI("MyProperty", "new","value");
For more information on this matter check the Adobe LiveDocs at:
http://livedocs.adobe.com/flex/3/html/help.html?content=03_Language_and_Syntax_19.html
Cheers