Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have two strings: "a" and "b". How to get "b" from "a". And "a" from "b" without if? Like:
var arr = ["a", "b"];
function reverse(str){
return arr[+!arr.indexOf(str)];
}
but in more elegant way.
Many, many ways to do this.
var a = 'foo', b = 'bar',
arr = [a, b];
// dictionary object
var o = {};
o[a] = b;
o[b] = a;
function reverse(x) {
return o[x];
}
// equality with cast (+x or x|0)
function reverse(x) {
return arr[+(x === a)];
}
// or
function reverse(x) {
return arr[+(x === arr[0])];
}
If you just want to take turns between the two, you could write a generator
var reverse = (function () {
var i = 1;
return function () {
return arr[i = 1 - i];
}
}());
reverse(); // "foo"
reverse(); // "bar"
reverse(); // "foo"
You could do
return arr[(str=='a')%2]
or if you don't want to hardcode 'a'
return arr[(str==arr[0])%2]
or (using the same idea)
return arr[+(str==arr[0])]
It looks marginally cleaner than your solution but how is it better than using the ternary operator ?
Use the modulo operator.
var arr = ["a", "b"];
function reverse(str){
return arr[(arr.indexOf(str) + 1) % 2];
}
You can use char/ascii conversion:
function reverse(c) {
return String.fromCharCode(195 - c.charCodeAt(0))
}
Try it
alert(reverse('a'));
alert(reverse('b'));
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have a list with hundreds of items and I need to call myFunction() with one of those items. The parameter depends from another variable value. So I came up with something like this:
let list = [1, 2, 3, ...]
switch(value) {
case list[0]
myFunction(value);
break;
case list[1]
myFunction(value);
break;
case list...
}
Do I have to write hundreds of case statements or is there a better way?
You can put your functions in the list :
const functions = [a, b, c, d];
function a() { return "A"; }
function b() { return "B"; }
function c() { return "C"; }
function d() { return "D"; }
document.write(functions[0]());
Still the same if you have arguments :
const functions = [a, b, c, d];
function a(value) { return "A "+value; }
function b(value) { return "B "+value; }
function c(value) { return "C "+value; }
function d(value) { return "D "+value; }
document.write(functions[0]("myValue"));
But you have to ensure all functions have the same signature (parameters count, types, ...) or it will become a mess quickly.
let list = [1, 2, 3, ...]
switch(value) {
case list[0]
myFunction(value);
break;
case list[1]
myFunction(value);
break;
case list...
}
If "value" equals the list item, why not call myFunction(value) directly? If you need to verify value is in the array, you could use
if (list.includes(value)) {
myFunction(value);
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I was presented with question and I had no idea how to do it
add() - > returns 0
add(1)() -> returns 1
add(1)(2)() -> returns 3
add(1)(2)(3)(4)() -> 10
Basically it can go on
Here is my one line solution if you love aesthetics
const add = (val) => (val ? (arg) => (arg ? add(val + arg) : val) : 0);
console.log(add(1)(2)(3)())
For Readability:
const add = (val) => {
if (val) {
return (arg) => {
if (arg) {
return add(val + arg);
} else {
return val;
}
};
}
return 0;
};
console.log(add(1)(2)(3)())
Edit : Explaination
I'll try to explain it in a simple way
lets break it down with a example add(1)(2)(3)()
So it happens like this
add(1) is evaluated first
add(1) -> returns a function (say _add())
_add() is a closure so it has access to the val variable (with value 1) and has its own parameter args with value 2
_add(2) -> calls add() again with the result of the addition (val + args)
add(1)(2)(3)() becomes -> _add(2)(3)()
_add(2) checks if it has a parameter args and if it does then it computes val + args and returns add(val +args) else 0
_add(2)(3)() becomes -> add(3)(3)()
add(3) -> _add()
_add(3) -> val + args -> add(val+args) -> add(6)
add(3)(3)() becomes -> _add(6)()
add(6)() -> returns _add()
_add() this time no parameter so return the value
I hope I was able to explain, comment if you have any doubts, I'll try my best
You can access the arguments through the variable arguments. Read more about it here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
I'm using a basic for loop, mostly for clarity, to show case it below.
function add() {
var sum = 0;
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
/* Alternative loop
for (let number of arguments) {
sum += number;
} */
return sum;
}
console.log( add(1) );
console.log( add(1, 2) ); // returns 3
console.log( add(1, 2, 3, 4) ); // returns 10
I think you are looking for this.
function add(a){
func = function(b){
func.result+=b;
return func;
}
func.result = a;
return func;
}
console.log(add(2)(2).result);
Each sequential call returns the same function again. You can do it infinitely and access result as property of the returned function.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm trying to cipher a result of a sum into a base64 code.
var map = {
1: 'dG',
2: 'h2, 3: '
gF,
4: 'pz',
5: 'V0'
};
if (map.indexOf(sum1) > -1) {
ans = map.indexOf(sum1)
} else {
console.log("Incorrect");
}
I want to match my number (sum1) to the index of my array and save the letters to the variable ans.
I am new to programming and would appreciate if anyone can help me here. If I didn't explain well enough please ask for clarification.
The indexOf method is for arrays/strings so that is not going to work since you have an Object. You idea was right to check to see if the property exists, you just are doing it the wrong way.
The best way of checking to see if the property exists in an object is to use hasOwnProperty.
var map = {
1: 'dG',
2: 'h2',
3: 'gF',
4: 'pz',
5: 'V0'
};
function getText (obj, key) {
// if(obj.hasOwnProperty(key)){
// return obj[key];
// } else {
// return null;
// }
return obj.hasOwnProperty(key) ? obj[key] : null;
}
console.log(getText(map, 1));
console.log(getText(map, 5));
console.log(getText(map, 100));
But since you have strings, you do not have to use hasOwnProperty, you can just use a truthy check since strings evaluate to true
var map = {
1: 'dG',
2: 'h2',
3: 'gF',
4: 'pz',
5: 'V0'
};
function getText (obj, key) {
// if (obj[key]) {
// return obj[key];
// } else {
// return null;
// }
return obj[key] ? obj[key] : null;
}
console.log(getText(map, 1));
console.log(getText(map, 5));
console.log(getText(map, 100));
Or just use an array and not an object to hold your strings. The thing with arrays is the first index is ZERO so all the indexes would shift down one. So to make the 1 in your object match 1 in the array you have to put something in index 0.
var map = [null, 'dG', 'h2', 'gF', 'pz', 'V0'];
function getText (obj, key) {
// if (obj[key]) {
// return obj[key];
// } else {
// return null;
// }
return obj[key] ? obj[key] : null;
}
console.log(getText(map, 1));
console.log(getText(map, 5));
console.log(getText(map, 100));
I decided to augment given your comment in your question. Note that NONE of this has anything to do with a cipher...I will leave that to you to refactor in.
Fixed syntax in your object (it IS an object)
added ways to get both the keys and values of your object given its simple layout
use the values of your object obtained from the object as an array (values)
created a function passing in those values and one I wanted to look for
returned an object with some fun properties to show how to do that
var myObject = {
1: 'dG',
2: 'h2',
3: 'gF',
4: 'pz',
5: 'V0'
};
function doThing(myvalues, sum1) {
var ans = {
checked: sum1,
exists: false,
index: -1
};
var stuffindex = myvalues.indexOf(sum1);
var stuffExists = (stuffindex > -1);
ans.exists = stuffExists;
ans.index = stuffindex;
// console.log(ans);
return ans;
}
var keys = Object.keys(myObject);
console.log(keys);
var values = Object.values(myObject);
console.log(values);
console.log(doThing(values, 'pz'));
var checkfor = 'gF';
console.log("Compare:", checkfor == "gf");
console.log(checkfor, " exists? ", doThing(values, checkfor).exists);
console.log('gf', " exists? ", doThing(values, 'gf').exists);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm creating an object dynamically using dot notation. This part works fine! The issue I have is that I'm overwriting object on each iteration. Once it's set it should just add to the object to overwrite and replace the properties.
What am I doing wrong ?
E.g. price": { "minPrice": 1000, "maxPrice": 10000 } not { "minPrice": value} or { "maxPrice": value }.
ausedSet(params, key, value);
function ausedSet(object, key, value) {
var keys = key.split('.');
for (var i = 0; i < keys.length - 1; i++) {
object = object[keys[i]] = {};
}
object[keys[keys.length - 1]] = value;
return object;
}
function getValidParams(value, key) {
if (acceptedParameters.indexOf(key) > -1) {
populateObject(vm.filterParameters, key, value);
}
}
//vm.filterParameters returns these
var acceptedParameters = [
'postCode',
'distance',
'locale',
'vehicleCategory',
'resultOrder',
'longLatCoordinates',
'price.minPrice',
'price.maxPrice',
'pagination'
]
The issue here is that you're not saving a reference to the original object... you're overwriting your object variable in the for-loop and then returning the final value of that variable. Perhaps you should add a line like:
var current = object;
and then use current instead of object in the rest of your function. Then you can return object and it will be still be a reference to your original input.
Edit: OP wasn't using the return value to begin with, so my original solution didn't help. The problem was that OP was passing in related sets of keys ("price.minPrice", "price.maxPrice") and the function was overwriting the value of the initial shared key ("price"). The solution is to check if an object already exists at the key in question before assigning an empty one.
function populateObject(obj, keyString, value) {
var keys = keyString.split('.'),
curr = obj;
for (var i = 0; i < keys.length - 1; i++) {
if (!curr[keys[i]]) curr[keys[i]] = {};
curr = curr[keys[i]];
}
curr[keys[keys.length - 1]] = value;
return obj;
}
var myObject = { foo: 'bar' };
var result = populateObject(myObject, 'some.nested.keys', 'something');
result = populateObject(result, 'some.nested.other', 'test');
console.log(result === myObject);
console.log(result.foo === 'bar');
console.log(result.some.nested.keys === 'something');
console.log(result.some.nested.other === 'test');
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Example:
Version 1:
const foo = (arg1) => {
return (arg2) => {
return (arg3) => {
return arg1 + arg2 + arg3;
}
}
}
// called as part of a pipe:
const result = pipe(bar, foo(arg1)(arg2), baz);
Version 2:
const foo = (arg1, arg2, arg3) => {
return arg1 + arg2 + arg3;
}
// called as part of a pipe:
const result = pipe(bar, _curry(foo)(arg1)(arg2), baz);
The method implementation is much cleaner and more elegant in Version 2, however the call is a little uglier. Since method calls (hopefully) appear in more than one place in the codebase, I'm trying to decide which version has less drawbacks.
I hope I don't need to explain why I want to achieve using curried functions and passing single arguments. Please approach the question from a pro-functional programming standpoint.
Thanks in advance!
You can use the arguments object of the function in case you don't know how many arguments there could be like this:
function foo() {
var sum = 0;
for(var i = 0; i < arguments.length; i++)
sum += arguments[i];
return sum;
}
console.log(foo());
console.log(foo(1, 2, 3));
console.log(foo(5, 6, 3, 7, 1, 10));
And if you want a currying that is independent of the number of arguments without forcing it using _.curry, then use this:
function foo(a) {
var sum = 0;
var _ = function(a) {
if(a === undefined)
return sum;
else {
sum += a;
return _;
}
}
return _(a);
}
console.log(foo());
console.log(foo(1)(2)());
console.log(foo(1)(2)(7)(10)(5)());