How to always return a java.util.Vector - serverside-javascript

If the value in my control only have one value the following code will return a String, if there are more than one value the code will return a java.util.Vector.
getComponent("mycontrol").getValue();
I want this code to return a vector even if there is only one value.
I have seen several code snippets that converts my string to an Array, but I want to get back a vector.

There is no way to force a singular value to be returned as a java.util.vector (or Array for that matter). The only way would be to test to see if it is a vector, then build a vector if not. You could place it into a function and wrap the call into that... for example (this is untested code so you'll need to verify syntax, etc):
asVector(getComponent("mycontrol").getValue());
function asVector(obj) {
if (obj.constructor === java.util.Vector) {
return obj;
} else {
var x:java.util.Vector = new java.util.Vector();
x.add(obj);
return x;
}
}

Related

Currently, if we need to do reduce or forEach on iterable or iterator, would we just have to polyfill it?

First of all, does it'd make sense to have some array methods such as reduce or forEach also for iterables and iterators? Is it true that to use them and not wanting to blow up an array of a huge size, we just have to polyfill them for now?
Edit
What you propose is being worked on. There is a proposal at stage 2 of the TC39 process for adding a whole bunch of helper methods to the iterator prototype (so they'd be usable by collections) and the proposal includes the two you mention .forEach() and .reduce() along with a dozen others.
I don't yet fully understand how this is supposed to work because the spec talks about iterator helpers, but then shows using .reduce() on an actual Set instance directly, just like you would use it on an array. So, maybe the helpers are used by each class to implement their own method of that name. Since you typically want to reduce a collection, not reduce an iterator, that would make some sense. The iterator is just a tool used in the reduction of the collection, not the collection itself.
They redefine the .reduce() callback to only pass the accumulator and value (no index, no object). FYI, I discovered this by looking at the very end of https://node.green/. So, it is being worked on and since there is a proposed standard, you could polyfill it and you can find sample implementations for tons of proposed new iterator methods here.
Here's a polyfill for the proposed Set.prototype.reduce() and Map.prototype.reduce():
(function() {
if (!Set.prototype.reduce) {
Object.defineProperty(Set.prototype, "reduce", {value: reduce});
}
if (!Map.prototype.reduce) {
Object.defineProperty(Map.prototype, "reduce", {value: reduce});
}
function reduce(fn, initialValue) {
if (typeof fn !== "function") {
throw new TypeError("2nd argument to reduce must be function");
}
let noInitial = arguments.length < 2;
let accumulator = initialValue;
for (let [key, value] of this.entries()) {
// if no initial value, get it from the first value
if (noInitial) {
accumulator = value;
noInitial = false;
} else {
accumulator = fn(accumulator, key, value);
}
}
// if there was nothing to iterate and initialValue was not passed
// spec says this should be a TypeError
if (noInitial) {
throw new TypeError("iterable was empty and initalValue not passed")
}
return accumulator;
}
})();
// demo code
let s = new Set([1,2,3,4,5,6]);
let sum = s.reduce((total, val) => {
return total += val;
}, 0);
console.log(`Set Total = ${sum}`);
let m = new Map([['one',1],['two',2],['three',3],['four',4]]);
let sum2 = m.reduce((total, key, val) => {
return total += val;
}, 0);
console.log(`Map Total = ${sum2}`);
I have not quite figured out how a .reduce() method on a base Iterator class automatically makes it so that set.reduce() or map.reduce() will "just work". I'm not sure it does. I'm thinking that each class still has to wire up it's own .reduce() method, but it can use the helper implementation on the Iterator object to do so. Perhaps that's why they are called "helpers". They're just common functions that can be used to wire up your own top level method.
They can probably still be accessed on an iterator directly, but that doesn't seem how you would typically use them.
Original answer...
You do not really need forEach() because you can just use for/of on any iterable. So, if you really wanted forEach(), you would have to implement it yourself. I wouldn't call it a polyfill because there is no standard you're trying to fill-in for. As such, it would be better to make it a stand-alone function, not pollute the prototype in a non-standard way.
There are certainly some arguments for having a reduce() like function that works with an iterable if you're just trying to iterate and collect some single value from the iteration. Again, since there is no standard implementation for all iterables, you'd have to implement your own function that works with any iterable.
One problem with implementing reduce() for any arbitrary iterable is that Array.prototype.reduce() passes an index to the callback. This somewhat assumes that there is access by that index like an array has. But, some collections that have are an iterable do not have access by index. You could still create an index during the iteration and pass it to the callback as just a counter, but it could not necessarily be used the way the index is used when doing someArray.reduce().
Here's an implementation of reduce() that works on any iterable. For reference here's the spec for Array.prototype.reduce() which works off indexed access, not off an iterable which is why it can't be used directly on any iterable, but can be used on any Array-like object.
let s = new Set([1,2,3,4,5,6]);
function reduce(iterable, fn, initialValue) {
if (typeof fn !== "function") {
throw new TypeError("2nd argument to reduce must be function");
}
let initialValuePresent = arguments.length >= 3;
let accumulator = initialValue;
let cntr= 0;
for (let item of iterable) {
// if no initial value, get it from the first value
if (cntr === 0 && !initialValuePresent) {
accumulator = item;
} else {
accumulator = fn(accumulator, item, cntr, iterable);
}
++cntr;
}
// if there was nothing to iterate and initialValue was not passed
// spec says this should be a TypeError
if (cntr === 0 && !initialValuePresent) {
throw new TypeError("iterable was empty and initalValue not passed")
}
return accumulator;
}
let sum = reduce(s, (total, item, cntr, obj) => {
return total += item;
}, 0);
console.log(`Total = ${sum}`);

Web API controller returns empty JSON even if returned var is not empty

In my API, I have to return a json composed of 2 distinct objects, one is a unique entity and the other a list. When I return each separatly there is no problem, but when I try to return them as a single json, the result is empty, even though my var in the return ok(var) contains what is supposed to be returned.
The controller looks like this:
[System.Web.Mvc.HttpGet]
public IHttpActionResult GetOne(int id)
{
var x = Service.GetOne(id);
return Ok(x)
}
(If I put a breakpoint on the return line, I can see that x contains the single object and the list that I want in my json)
"Service" is where I merge the 2 objects by caling a model constructor that takes the single object and the list as input, it looks like this:
public class mergedObject
{
IEnumerable<SingleObject> y;
IEnumerable<ListObject> z;
public mergedObject GetOne(int Id)
{
mergedObject x = new mergedObject(RepoSingleObject.getOne(Id) a,
RepoList.GetAll(Id) b)
this.y = a
this.z = b
}
It calls the corresponding repository(which contains the sql query) for each object and I know this part is working, since like I said earlier, I can properly return each object individually.
The console returns absolutely no error, I did everything the same way as with the individual objects, except for the merging and when I use breakpoints everything seems to go fine, but yet, using postman to test it, I always get an empty return. Does anyone have an explanation?
EDIT
The controller is derived from ApiController + added full definition of the mergedObject class up there. I use IEnumerable even on the single object because I reuse some part of the code where this single element is in fact a list, so I figured it would only be a list of 1 element and wouldn't cause any problem.

Which is better for returning result of some method or instance of a class? and why?

I was just wondered which is better way for returning some result of function or instance of Class?
1)
FN() {
var result = callSomeFN();
return result;
}
InitClass(int typeId): MyClass {
MyClass class = new MyClass(typeId);
return class;
}
2)
FN() {
return callSomeFN();
}
InitClass(int typeId): MyClass {
return new MyClass(typeId);
}
The only difference I see here is the declaration of a variable. I wouldn't say one is better than the other. If the variable is never going to be used why bother defining it? Just return.
I suppose if you really wanted to nitpick it would depend on if you're returning a value or reference type. If it's a reference it doesn't matter since you're going to store something in memory and return a pointer (both the variable and the return value are just pointers to the same memory space). If it's a value type it will end up copying the value and disposing of the version within the function scope. If the variable is never used why create something just to destroy it? The default behavior would be highly language dependent, which you didn't specify.

How to turn a Ceylon Sequential or array into a generic Tuple with the appropriate type?

I've got a generic function that needs to create a Tuple to call a function whose arguments I don't know the types of.
Something like this (except array in this example is created by some external code, so I can't just apply the function directly):
Result apply<Result, Where>(
Anything[] array,
Callable<Result, Where> fun)
given Where satisfies Anything[] => nothing;
Is there a type-safe way to implement this method and get the function to be called with the given arguments?
This cannot be done completely type-safely... but assuming that the array indeed contains elements of the correct types as they should appear in a Tuple of type Where, the following function will do the trick:
Tuple<Anything, Anything, Anything> typedTuple({Anything+} array) {
if (exists second = array.rest.first) {
return Tuple(array.first, typedTuple({ second }.chain(array.rest.rest)));
}
else {
return Tuple(array.first, []);
}
}
And apply gets implemented as:
Result apply<Result, Where>(
[Anything+] array,
Callable<Result, Where> fun)
given Where satisfies Anything[] {
value tuple = typedTuple(array);
assert(is Where tuple);
return fun(*tuple);
}
There's nothing relating the type of array to the parameters of fun, so that signature can't possibly be implemented in a type-safe way. You're not constraining the type of array at all; it could contain anything. How in principle would a type-safe implementation handle the case where fun expects [String, Integer] but array is [Boolean+]?

How to define the return type of AS3 method that may return or not return a result?

public function t()
{
if(xxx)return xxx;
//don't return anything
}
How to define the return type for such method?
A function either has to return nothing, or return something - it can't do both. The reason being, what if you write this code:
var someValue = someFunction();
How would this code be handled if sometimes someFunction returned a value, and sometimes it didn't?
Your problem is a really common one, though, and there are several ways to work around it.
Sentinel Values
You can return special-case values that you treat as non-values (such as null, NaN, "", or -1). These special-case values are called sentinel values. The users of your function (maybe your own code) would check the result after calling it. If it gets one of the sentinel values back, it doesn't use the result.
Try-style Functions
You could also use a pattern commonly used in C#/.Net that they call "Try-methods", but you can call "Try-functions". Actionscript doesn't work exactly like C#, but we can get close enough for this pattern to work.
To do this, return Boolean, returning true if you have a value, and false if you don't. Then give your function an Object parameter, and populate a property with the actual return value:
function trySomeFunction(result:Object) : Boolean
{
if(xxx)
{
result.Value = xxx;
return true;
}
return false;
}
// ...
var result:Object = { Value:null };
if(trySomeFunction(result))
{
// Do something with the value here
}
Exceptions
If your method failed to do what it promised to do, you can throw an exception. Then you don't have to worry about what gets returned, because your code just dies.
Exceptions are great because people who call your code don't have to learn as much. They don't have to know that your function only succeeded if it doesn't return some magic value that is different for every function, they don't need to check if your function returns true/false, and they don't need to know that some property gets populated on an object when the function succeeded.
Without exceptions, if they forget to check for your special value, or the result of a "Try-function", an error might happen further on in the program. Or it might not happen at all, and the program will continue running, but be broken. In these cases, it is much harder to track down the problem.
With exceptions, your code just blows up the second it detects a problem, and gives you the line of code where your program realized it couldn't work correctly.
If it is normal and okay for your function to fail, though, you probably shouldn't throw an exception. You should probably use a "Try-function" or a sentinel value instead.
Everything that Merlyn says is fine, though perhaps a bit of overkill. If your method needs the potential to return null, then just pass xxx back whether it's null or not...
public function t():MyReturnType
{
return xxx;
}
... since you're going to have to do check the special condition in the calling method anyway:
public function caller():void
{
var value:MyReturnType = t();
if (value)
doSomethingPositive();
else
copeWithNullState();
}
Some people think that this is wrong and advocate creating a special 'null value' object in your return class, like this:
public class MyReturnType
{
public static const NULL:MyReturnType = new MyReturnType(null);
public function MyReturnType(identifier:String)
...
}
then in your function either return an interesting MyReturnType or NULL:
public function t():MyReturnType
{
return xxx || MyReturnType.NULL;
}
but then you've not really improved your caller method so why bother?
public function caller():void
{
var value:MyReturnType = t();
if (value != MyReturnType.NULL)
doSomethingPositive();
else
copeWithNullState();
}
Whatever you choose to do, eventually you're just going to have to test for special cases in the caller method. Personally I'd say it's better to keep it as simple as possible, and the special 'null value' in your class is over-complication.
I write plenty of functions that might return an object reference, but may also return null, like this:
public function findThingById( id:int ):MyThingType
{
... code here to search for/load/lookup thing with matching id
if (found)
{
return thing;
}
return null;
}
Wherever you call a function that might return null, you would either test the return value for null explicitly, or if you expect null just don't do anything with the return value. For built-in data types, you would use a special value rather than null (like NaN for Numbers illustrated above), but the principle is the same.
public function t():type
{
if(xxx)return xxx;
//don't return anything
}
so something like:
private function derp():void{
}
private function derp2():int{
}
private function derp3():Boolean{
}
etc
its always good practice to define the return type, and return an indicator variable if false (i.e return -1 for number), but if its really necessary you can do this:
public function t()
{
if(xxx)return xxx;
//don't return anything
}
don't specify a return type at all, and either it will return xxx or undefined, but I highly encourage using a return type.
But since flash runs on virtual memory it can basically adapt to your return type so it makes it a little flexible so you can return what ever.
EDIT:
public function t()
{
if(true){
return xxx; //xxx can by of any type
}
return NaN
}
EDIT:
so lets say you want the condition with a return type of int you would have
public function t():int
{
if(true){
return xxx; //where xxx != -1
}
return -1
}
this when we get back any number other then negative 1 we know the condition was true, but if we get -1 the condition was false. But if you numbers are any real numbers, use NaN keyword:
public function t():Number
{
if(true){
return xxx; //where xxx != -1
}
return NaN
}
this way if you get NaN back it means your condition was false
I should also mention that when your dealing with NaN use the isNaN() to determine if the return type was NaN or not:
example:
if(isNaN(t()) == true){
//if condition in function t() was false;
}
There is no way a single function can return void as well as returning a type. This is because void is not part of any inheritance chain, it is a top level concept meaning something very specific; it doesn't return anything.
Don't get confused between null and void, undefined and void, NaN and void. They are different concepts.
The answer to your question is simply that it can't, nor should it be done. When you hit a problem like this, it's good practice to step back and ask 'why' do you need to do this.
I would highly encourage that you mark this question as closed, and instead posted a higher level problem. For example,
How would I structure a class that has a variable xxx that does this and that and will be eventually set to a number when the user clicks. But if the user never clicks, it will be unset.... ecetera ecetera....
If you are 100% convinced you should do something like you're asking, you could 'fake' it by
function f():* {
var xxx:Number = 999;
if(xxx) {
return xxx;
} else {
return undefined;
}
}
var xx:* = f();
trace(xx);
But remember, from that point onwards you will need to check everytime xx is used to see if it undefined. Otherwise it will lead to errors.