reduce javascript code when using the map function - javascript

I want to iterate over an array and do something to each of the element
d = d.map(function(d){
return _.omit(d, 'password');
})
d = d.map(function(d){
return d.toString();
})
these functions are working correctly. But after it showed up too many times the code becomes really messy.
So I was wondering if there's easier ways to do what I want to do? I am hoping to reduce the code to one line only using bind or apply keywords or some modules (maybe lodash or underscore..). Is this possible?

If you're using a version of JavaScript that supports arrow functions, you could use those:
d = d.map((d) => _.omit(d, 'password'));
Or if you're repeating the same code a lot, you can make helper functions:
function removePasswords(d) {
return d.map(function (d) {
return _.omit(d, 'password');
});
}
d = removePasswords(d);
If you're performing a lot of maps one after the other, you can combine their contents
d = d.map(function(d) {
return _.omit(d, 'password').toString();
});
Otherwise, I don't think it's going to get much shorter than what you already have. It's already pretty short.
You may want to look into using Coffeescript if you feel that JavaScript is too verbose:
d = d.map (d) -> _.omit(d, 'password')

Related

Calling a variable from inside another function is bad?

I want to make my JS code to be less repetitive with an organized look. But I don't know if calling a function from inside another function is a bad practice, like Global Variables.
I share a piece of the code here.
thanks.
function getEx() {
return document.getElementById('example')
}
function getExTwo() {
return document.getElementById("exampleTwo");
}
function getTheValue() {
let getExValue = getEx();
let getExTwoValue = getExTwo();
}
Calling a function from within another function is absolutely not bad coding. That's part of what functions are for, really -- breaking up logical processes into smaller pieces.
Here's an example of how this can work.
// Note: This is new ES6/ES7 syntax for writing JavaScript functions.
// I'm using it here because it's very terse.
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;
const square = (a) => multiply(a, a);
const sumOfSquares = (arr) => {
let sum = 0;
arr.forEach(number => sum += square(number));
return sum;
};
In the (simplified) example above, we use different functions to break up the distinct logical pieces of the problem into smaller, more manageable problems. For example, to calculate the sum of the squares of the array [1, 10, 12], we want to be able to add things and we want to be able to square things, so it's a good idea to create functions for performing each of those steps. We might even want to use other functions within those functions (e.g. calling multiply from within square).
Now, is it possible to go overboard with creating new functions? Yes. Try to avoid writing multiple functions that are basically the same. But otherwise... go nuts!
Calling a function from within another function is not bad. It is a recommended way of reducing repetition by breaking your code into smaller pieces, each handling some specific logic.
Here is a simplified version of your code:
// ps: $ is not from jquery it is just a normal variable.
const $ = document.querySelector
const getValues = () => {
const firstVal = $('#example')
const secondVal = $('#exampleTwo')
}

Javascript: Weird syntactic element

I'm having trouble understanding this piece of Javascript code:
var _ref3 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () {
if (actualArgs.length === 0) {
const sandbox = yield getValidSandbox(curDir);
// It's just a status command. Print the command that would be
// used to setup the environment along with status of
// the build processes, staleness, package validity etc.
let envForThisPackageScripts = PackageEnvironment.calculateEnvironment(sandbox, sandbox.packageInfo, { useLooseEnvironment: true });
console.log(PackageEnvironment.printEnvironment(envForThisPackageScripts));
} else {
let builtInCommandName = actualArgs[0];
let builtInCommand = builtInCommands[builtInCommandName];
if (builtInCommand) {
builtInCommand(curDir, ...process.argv.slice(3));
} else {
console.error(`unknown command: ${builtInCommandName}`);
}
}
});
What exactly is _ref3 ? a function ? a tuple ? I'm confused
I would not like to read your code for you but i think, with a little help you could understand this code your self. I guess you need help with the various new syntax being used in the code above. I'll try to note down those so that you can understand all of this code yourself.
(0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function*{})
This line basically is similar to
(0,x)(function*{})
where x is a function which takes a generator function as an argument.
Whenever you have a line of the form (x,y) it will always return the last value. So in the case of(x,y) it will return y. If its (0,x) it will return x. Thus in code which you posted, the first line will return (_asyncToGenerator2 || _load_asyncToGenerator()).default.
You could now translate the code to
((_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* {})
This means that above code will return a function which takes a generator as argument
If you need more information on generator you could go here
The generator function has attributes like yield. They are pretty useful especially to handle asynchronous operations. It streamlines your code and makes it easy to read. To get more information what yield means, you could go here and here
You could also see some lines like these in the code.
builtInCommand(curDir, ...process.argv.slice(3));
This is basically spread operators being used. Spread operators basically allow an expression to be expanded in places where multiple arguments are expected. You could go here
to know more about spread operators.
Hope you will be able to read the above code yourself after you understand the concepts.

Iterating over Linked List using Functional programming paradigm

I have a simple Linked list in my project. The project uses underscore.js. I am trying to think of a way to iterate over the linked list using functional programming techniques. Currently, I have the following:
while(cell.next) {
nxt = cell.next;
//check if next cell fulfills some condition. If condition is met,
// loop breaks
}
Is there any way to implement the above in a functional manner (using underscore.js library)?
Thanks in advance.
Not sure how underscore would factor in. Doesn't really seem necessary to get functional style code.
function doCell(c) {
if (!c || your_condition_is_met)
return c;
return doCell(c.next);
}
var result = doCell(cell);
Not sure what the result is supposed to be, so I just returned the current cell if the condition is met.
You could abstract some of it away into a reusable function if you wish.
function nextWhile(v, callback) {
if (!v || callback(v))
return v;
return nextWhile(v.next, callback);
}
Then use it like this:
var result = nextWhile(cell, function(cell) {
return your_condition_is_met;
});
And this lets you create reusable functions.
function cell_is_something(cell) {
return your_condition_is_met;
}
Which cleans up and documents your code.
var result = nextWhile(cell, cell_is_something);

Programming optional ignorance

In Javascript what is the best way to handle scenarios when you have a set of arrays to perform tasks on sets of data and sometimes you do not want to include all of the arrays but instead a combination.
My arrays are labeled in this small snippet L,C,H,V,B,A,S and to put things into perspective the code is around 2500 lines like this. (I have removed code notes from this post)
if(C[0].length>0){
L=L[1].concat(+(MIN.apply(this,L[0])).toFixed(7));
C=C[1].concat(C[0][0]);
H=H[1].concat(+(MAX.apply(this,H[0])).toFixed(7));
V=V[1].concat((V[0].reduce(function(a,b){return a+b}))/(V[0].length));
B=B[1].concat((MAX.apply(this,B[0])-MIN.apply(this,B[0]))/2);
A=A[1].concat((MAX.apply(this,A[0])-MIN.apply(this,A[0]))/2);
D=D[1].concat((D[0].reduce(function(a,b){return a+b}))/(D[0].length));
S=S[1].concat((S[0].reduce(function(a,b){return a+b}))/(S[0].length));
}
It would seem counter-productive in this case to litter the code with tones of bool conditions asking on each loop or code section if an array was included in the task and even more silly to ask inside each loop iteration with say an inline condition as these would also slow down the processing and also make the code look like a maze or rabbit hole.
Is there a logical method / library to ignore instruction or skip if an option was set to false
All I have come up with so far is kind of pointless inline thing
var op=[0,1,1,0,0,0,0,0]; //options
var L=[],C=[],H=[],V=[],B=[],A=[],D=[],S=[];
op[0]&&[L[0]=1];
op[1]&&[C[0]=1,console.log('test, do more than one thing')];
op[2]&&[H[0]=1];
op[3]&&[V[0]=1];
op[4]&&[B[0]=1];
op[5]&&[A[0]=1];
op[6]&&[A[0]=1];
It works in that it sets only C[0] and H[0] to 1 as the options require, but it fails as it needs to ask seven questions per iteration of a loop as it may be done inside a loop. Rather than make seven versions of the the loop or code section, and rather than asking questions inside each loop is there another style / method?
I have also noticed that if I create an array then at some point make it equal to NaN rather than undefined or null the console does not complain
var L=[],C=[],H=[],V=[],B=[],A=[],D=[],S=[];
L=NaN;
L[0]=1;
//1
console.log(L); //NaN
L=undefined;
L[0]=1
//TypeError: Cannot set property '0' of undefined
L=null
L[0]=1
//TypeError: Cannot set property '0' of null
Am I getting warmer? I would assume that if I performed some math on L[0] when isNaN(L)===true that the math is being done but not stored so the line isn't being ignored really..
If I understand what you want I would do something like this.
var op = [...],
opchoice = {
//these can return nothing, no operation, or a new value.
'true': function(val){ /*operation do if true*/ },
'false': function(val){ /*operation do if false*/ },
//add more operations here.
//keys must be strings, or transformed into strings with operation method.
operation: function(val){
//make the boolean a string key.
return this[''+(val == 'something')](val);
}
};
var endop = [];//need this to prevent infinite recursion(loop).
var val;
while(val = op.shift()){
//a queue operation.
endop.push(opchoice.operation(val));
}
I'm sure this is not exactly what you want, but it's close to fulfilling the want of not having a ton of conditions every where.
Your other option is on every line do this.
A = isNaN(A) ? A.concat(...) : A;
Personally I prefer the other method.
It looks like you repeat many of the operations. These operations should be functions so at least you do not redefine the same function over and over again (it is also an optimization to do so).
function get_min(x)
{
return +(MIN.apply(this, a[0])).toFixed(7);
}
function get_max(x)
{
return +(MAX.apply(this, a[0])).toFixed(7);
}
function get_average(x)
{
return (x[0].reduce(function(a, b) {return a + b})) / (x[0].length);
}
function get_mean(x)
{
return (MAX.apply(this, x[0]) - MIN.apply(this, x[0])) / 2;
}
if(C[0].length > 0)
{
L = L[1].concat(get_min(L));
C = C[1].concat(C[0][0]);
H = H[1].concat(get_max(H));
V = V[1].concat(get_average(V));
B = B[1].concat(get_mean(B));
A = A[1].concat(get_mean(A);
D = D[1].concat(get_average(D));
S = S[1].concat(get_average(S));
}
You could also define an object with prototype functions, but it is not clear whether it would be useful (outside of putting those functions in a namespace).
In regard to the idea/concept of having a test, what you've found is probably the best way in JavaScript.
op[0] && S = S[1].concat(get_average(S));
And if you want to apply multiple operators when op[0] is true, use parenthesis and commas:
op[3] && (V = V[1].concat(get_average(V)),
B = B[1].concat(get_mean(B)),
A = A[1].concat(get_mean(A));
op[0] && (D = D[1].concat(get_average(D)),
S = S[1].concat(get_average(S)));
However, this is not any clearer, to a programmer, than an if() block as shown in your question. (Actually, many programmers may have to read it 2 or 3 times before getting it.)
Yet, there is another solution which is to use another function layer. In that last example, you would do something like this:
function VBA()
{
V = V[1].concat(get_average(V));
B = B[1].concat(get_mean(B));
A = A[1].concat(get_mean(A));
}
function DS()
{
D = D[1].concat(get_average(D));
S = S[1].concat(get_average(S));
}
op = [DS,null,null,VBA,null,null,...];
for(key in op)
{
// optional: if(op[key].hasOwnProperty(key)) ... -- verify that we defined that key
if(op[key])
{
op[key](); // call function
}
}
So in other words you have an array of functions and can use a for() loop to go through the various items and if defined, call the function.
All of that will very much depend on the number of combinations you have. You mentioned 2,500 lines of code, but the number of permutations may be such that writing it one way or the other will possibly not reduce the total number of lines, but it will make it easier to maintain because many lines are moved to much smaller code snippet making the overall program easier to understand.
P.S. To make it easier to read and debug later, I strongly suggest you put more spaces everywhere, as shown above. If you want to save space, use a compressor (minimizer), Google or Yahoo! both have one that do a really good job. No need to write your code pre-compressed.

Create list/array from a dictionary using custom function

I've such an input array that every element of the array is a dictionary {x:a_int, y:a_int}. Now I need to extract all y values and create a new array, so that it can be used to calculate the maximum of all y-values. Here is my current code:
var inputArray = [{x:1,y:100},{x:2,y:101},{x:3,y:103}];
function extractY(data) {
var result = [];
data.forEach(function (item) {
result.push(item.y);
});
return result;
}
// Test code
var yArray = extractY(inputArray);
console.log(Math.max.apply(Math, yArray));
I want to make code shorter. As I'm new to javascript, I'd like to know, if it possible to shorten the function extractY(). My imagination is to have a transformation function. The code should not rely on jQuery and does not have to consider old browser compatibility.
You can simply use Array.prototype.map, which will create a new Array with the values returned by the function passed to it, like this
function extractY(data) {
return data.map(function (item) {
return item.y;
});
}
Or you can simply write the same as
console.log(Math.max.apply(Math, inputArray.map(function(item) {
return item.y;
})));
Using reduce, you can get the maximum y value directly:
inputArray.reduce(function(prev, curr) {
return prev.y > curr.y ? prev : curr;
}).y
With underscore:
_.max(_.pick(inputArray, 'y'))
With d3:
d3.max(inputArray, function(d) { return d.y; })
Note in response to #AmitJoki's comment: Yes, I know this question was not tagged underscore. If you don't want to use underscore, feel free to ignore this answer. Having said that, underscore is a highly useful utility toolbelt that is perfect for solving problems such as this, among many other things. It's exhaustively tested and robust and efficient and handles all the edge cases correctly. Unlike certain other bloated libraries, it's quite lightweight and is well worth learning.
I doubt if it falls within the realm of common sense to imply that the failure to mark a question "underscore" means that underscore-based answers are somehow not acceptable, considering that it's easy to imagine that in many cases the OP may not even be aware of that option and might welcome a suggestion about how to write more compact code, while learning a useful tool in the process.

Categories

Resources