Javascript have a function return no value - javascript

I've been trying to make a function that will not return any value if two values are the same between two arrays. I've searched my question several ways on here and on google, and everything I find says that a function HAS to return a value, and there's no way to avoid doing it. So I'm directly asking if there is a way, and if not how can I get around what I'm trying to do?
var bannedValues = [2, 4, 6, 8]; //Even numbers 1-8
var inputValues = [1, 2, 3, 4, 5, 6, 7, 8]; //All numbers 1-8
var filterValues = function(value)
{
for (var number of bannedValues)
{
if (value == number)
{
return; //I want this to return absolutely nothing, not even an empty value
}
}
return value;
}
var filteredValues = inputValues.map(filterValues);
console.log(filteredValues);
/* The array just gains "undefined" values in the places I want there
to be no value, so the array is a length of 8 instead of the 4 I want.
Can I somehow take those out or can I just not have them there in the first place? */

If you are using map, you are actually iterating through your array and manipulate it if necessary, but this will not remove item from array. Instead of map try filter
var bannedValues = [2, 4, 6, 8]; //Even numbers 1-8
var inputValues = [1, 2, 3, 4, 5, 6, 7, 8]; //All numbers 1-8
var filterValues = function(value) {
return bannedValues.indexOf(value)===-1;
}
var filteredValues = inputValues.filter(filterValues);
console.log(filteredValues);
result will be
(4) [1, 3, 5, 7]

Use the Array.filter() method:
var bannedValues = [2, 4, 6, 8]; //Even numbers 1-8
var inputValues = [1, 2, 3, 4, 5, 6, 7, 8]; //All numbers 1-8
filteredValues = inputValues.filter( function( el ) {
return bannedValues.indexOf( el ) < 0;
} );
/*This is another way to do it, but not supported in IE*/
filteredValues = inputValues.filter( function( el ) {
return !bannedValues.includes( el );
} );
console.log(filteredValues);
Lodash has an utility function for this as well: see here

JavaScript functions always have a return value. There's nothing you can do about that.
It's impossible I think to tell the difference between a function that explicitly returns undefined and one that just returns with no value expression.
If you want to do something like .map() but have the option of skipping values, use .reduce() instead:
var filterValues = function(accumulator, value)
{
for (var number of bannedValues)
{
if (value == number)
{
return accumulator;
}
}
accumulator.push(value);
return accumulator;
}
var filteredValues = inputValues.reduce(filterValues, []);

Related

Library Function to have Unique Items (remove duplicated) Array is not running

I am trying to make a "Library Function" to remove duplicated array entries. I have written following snippet but it doesn't seem to work. Can anyone help fix it?
var arr1 = [5, 4, 2, 6, 9, 2, 8, 1, 6];
Array.prototype.unique = function(arr){
var result = [];
arr.forEach(item){
if(result.indexOf(item) === -1){
result.push(item);
}
}
return result;
}
console.log(arr1.unique());
I believe what you are attempting to do is the following. The small change I made was to use the this keyword to reference the array itself. Also the function needs to be inside the foreach(fn => {}).
Array.prototype.unique = function() {
var result = [];
this.forEach(function(item) {
if(result.indexOf(item) === -1) {
result.push(item);
}
})
return result;
}
Making a version that uses an arrow function inside the foreach loop and uses includes, so you have some options.
Array.prototype.unique = function() {
var result = [];
this.forEach(item => {
if (!result.includes(item)) {
result.push(item);
}
})
return result;
}
Maybe this will help you.
No need to pass an argument, you can access array using this
var arr1 = [5, 4, 2, 6, 9, 2, 8, 1, 6];
Array.prototype.unique = function() {
var result = [];
this.forEach((item) => {
if (result.indexOf(item) === -1) {
result.push(item);
}
});
return result;
}
console.log(arr1.unique());
In console.log() must be :
console.log(arr1.unique(arr1));
your unique function receives an array as a parameter
Easy way to do this, You can try this
let arr1 = [5, 4, 2, 6, 9, 2, 8, 1, 6];
let result= Array.from(new Set(arr1))
console.log(result)

Prevent function stopping at first condition met

May be this is kind of a beginner question... I'm trying to prevent a function stopping when it met first condition. Here is my example:
// Array of values
const valArray = [1, 4, 9, 16];
// Array of index values
const indArr = [0, 2];
const multipliedVal = valArray.map((val, index) => {
for (let i of indArr) {
// Case 1
if (index == i) return val * 3;
// Case 2
if (index == i) return val * 3;
else return val;
}
});
console.log(multipliedVal);
In case 1 it outputs:
Array [3, undefined, 27, undefined]
In case 2 it outputs:
Array [3, 4, 9, 16]
I want to apply case 2 in a way it will multiply values of valArray by 3 if their index are 0 and 2 (like defined in indArr), but map function stops running after first condition met. It does multiply 1 by 3, but not 9. I want the output to be:
Array [3, 4, 27, 16]
I tried some other stuff with the splice method but did not figure that out. I bet some recursion would be involved with what I'm trying to achieve, but can't figure out how to do that.
May be someone can help? Thanks.
Check if index is present in indArr using indexOf. If so then multiply the value and return else return the value
const valArray = [1, 4, 9, 16];
// Array of index values
const indArr = [0, 2];
const multipliedVal = valArray.map((val, index) => {
if (indArr.indexOf(index) !== -1) {
return val * 3
}
return val;
});
console.log(multipliedVal);

Condition inside forEach

I have two arrays:
firstArray = [1, 2, 3, 4];
secondArray = [5, 6, 7, 8];
I must use their elements to compute another one inside a forEach.
_.forEach(firstArray, (data, i) => {
myValue: firstArray[i] + secondArray[i]
});
This works fine. But I want to ignore the last element of the second array all the time. So in this case, for i = 3 the result should be 4, not 4+8, ignoring the last value of the second array.
I know that using an if statement wouldn't work but is there a way to do it?
I mean inside the forEach, removing the last element before the function doesn't work in this case.
UPDATE: I received some good answers but all of them were using something different than forEach. I would like to know if there is a way to do it with this function or not.
You can just check if i is the last element of the second array using array.length.
I don't really understand your forEach code, but you could use ternary operators in it:
_.forEach(firstArray, (data, i) => {
myValue: firstArray[i] + (i === secondArray.length - 1 ? 0 : secondArray[i])
});
You could reduce and map the arrays.
var firstArray = [1, 2, 3, 4],
secondArray = [5, 6, 7, 8],
result = [firstArray, secondArray].reduce((a, b) => a.map((v, i) => v + b[i]));
console.log(result);
I would do this:
firstArray = [1, 2, 3, 4];
secondArray = [5, 6, 7, 8];
for (let i = 0; i < firstArray.length; i++){
if(i === firstArray.length - 1) {
myValue = firstArray[i];
} else {
myValue = firstArray[i] + secondArray[i]
}
}
Use map
firstArray = [1, 2, 3, 4];
secondArray = [5, 6, 7, 8];
var output = firstArray.map( ( s, i, ar ) => s + (i == ar.length - 1 ? 0 : secondArray[i] ) );
UPDATE: I received some good answers but all of them were using
something different than forEach. I would like to know if there is a
way to do it with this function or not.
using forEach, you would need another array to capture the sum
firstArray = [1, 2, 3, 4];
secondArray = [5, 6, 7, 8];
var myValue = [];
firstArray.map( ( s, i, ar ) => myValue.push( s + (i == ar.length - 1 ? 0 : secondArray[i] ) ) );
now myValue is
[6, 8, 10, 4]
Hence map seems to be a less-verbose approach.

How to compare multiple arrays and return an array with unique values in javascript?

I would like to compare multiple array and finally have an array that contain all unique values from different array. I tried to:
1,Use the filter method to compare the difference between 2 arrays
2,Call a for loop to input the arrays into the filter method
and the code is as follows
function diffArray(arr1, arr2) {
function filterfunction (arr1, arr2) {
return arr1.filter(function(item) {
return arr2.indexOf(item) === -1;
});
}
return filterfunction (arr1,arr2).concat(filterfunction(arr2,arr1));
}
function extractArray() {
var args = Array.prototype.slice.call(arguments);
for (var i =0; i < args.length; i++) {
diffArray(args[i],args[i+1]);
}
}
extractArray([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]);
However it does not work and return the error message "Cannot read property 'indexOf' of underfined" .... What's wrong with the logic and what should I change to make it works?
Many thanks for your help in advance!
Re: For all that mark this issue as duplicated ... what I am looking for, is a solution that can let me to put as many arrays as I want for input and reduce all the difference (e.g input 10000 arrays and return 1 array for unique value), but not only comparing 2 arrays .. The solutions that I have seen are always with 2 arrays only.
I don't use filters or anything of the sort but it will get the job done. I first create an empty array and concat the next array to it. Then I pass it to delete the duplicates and return the newly "filtered" array back for use.
function deleteDuplicates(a){
for(var i = a.length - 1; i >= 0; i--){
if(a.indexOf(a[i]) !== i){
a.splice(i, 1);
}
}
return a;
}
function extractArray() {
var args = Array.prototype.slice.call(arguments), arr = [];
for (var i = 0; i < args.length; i++) {
arr = deleteDuplicates(arr.concat(args[i]));
}
return arr;
}
var arr = extractArray([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]);
console.log(arr) //[3, 2, 5, 1, 7, 4, 6]

Determine which array is lengthier JavaScript

SORRY I HAD TO CHANGE THE QUESTION I SCREWED UP. The purpose is to use the Math.max function to determine the lengthiest array. I needed to add an additional parameter to make it practical because everyone was using > instead of Math.max. I was writing this example to fast and didn't think of that.
Is there an easier way to do this? The purpose is to be able to take many arguments (more than two) and find out which has a larger length. I'd like it to be dynamic, so It seems I need to give a name property to each array before passing them in. This is the only way to find an arrays name right?
var arrayLogA = [8, 7, 5, 4, 6, 8, 0, 9, 4];
arrayLogA.name = 'arrayLogA';
var arrayLogB = [1, 5, 4, 6, 5, 9, 3, 2, 7, 3, 2]
arrayLogB.name = 'arrayLogB';
var arrayLogC = [1, 6, 9, 3, 3, 7, 3, 2]
arrayLogC.name = 'arrayLogC';
function returnLargestArray(a, b, C) {
...
}
returnLargestArray(arrayLogA, arrayLogB);
ok, this is more practical, if I'm going to explain the Math.max function and also return the largest, I'm going to have to rethink the function. Sorry for any confusion. I typically write good questions but I think I rushed this one. Very sorry.
I may need to pass additional parameters in. SO maybe I should not have used a, b, c as the arguments.
function returnLargestArray(a,b){
if(!a || typeof a.length =="undefined" ||
!b || typeof b.length =="undefined") {return;}
if(a.length==b.length){/*return some value of your choosing*/}
return a.length>b.length?a:b;
}
returnLargestArray([1,2,3],[1,2,3,4]);
But beware of caveats for non "simple" arrays.
Non-array objects with a length property
Arrays which have had indexes explicitly set, will be counted based on their max index, not the number of "used" indexes
Alright, this might be a little less than ideal, and certainly feels a bit weird, but you could do something like this.
var arrayLogA = [8, 7, 5, 4, 6, 8, 0, 9, 4];
arrayLogA.name = 'arrayLogA';
var arrayLogB = [1, 5, 4, 6, 5, 9, 3, 2, 7, 3, 2];
arrayLogB.name = 'arrayLogB';
var arrayLogC = [1, 6, 9, 3, 3, 7, 3, 2];
arrayLogC.name = 'arrayLogC';
...
var arrayLogN = [ ... ];
arrayLogN.name = 'arrayLogN';
function returnLargestArray(/* some unknown number of arrays */) {
var lengths = [];
// store lengths of each array
for(var i = 0; i < arguments.length; i++){
lengths.push(arguments[i].length);
}
// use Math.max to get biggest length
var largest = Math.max.apply(null, lengths);
// use indexOf to get the index of biggest length
var indexOfLargest = lengths.indexOf(largest);
// use the indexOfLargest to return that value from arguments
return arguments[indexOfLargest].name;
}
returnLargestArray(arrayLogA, arrayLogB, arrayLogC, ..., arrayLogN);
Using this method will return to you the lengthiest array passed in to the function, without requiring you to name each array.
Just a quick note: this function invokes Math.max.apply rather than just Math.max because Math.max expects a number of inputs, rather than just one array that we're trying to find the maximum within. To make Math.max work on an array, we have to use Math.max.apply.
I hope this does what you want!
Edit: Added name properties to the arrays in order to return name at end of function.
Try this. (I haven't tested it yet, but it makes sense!)
function returnLargestArray(a, b) {
if (a.length > b.length) {
return console.log("winner: "+ a.name);
} else {
return console.log("winner: "+ b.name);
}
}
If they're the same length that will fail, but you get the idea.
What about something like:
if (a.length > b.length) {
console.log("winner: "+ a.name);
return a;
else {
console.log("winner: "+ b.name);
return b;
}
or if you want it to be really short:
return a.length > b.length ? a : b;
As a side note, your logic could use a little work. Right now it returns the output from console.log, which is undefined. Returning the array makes more sense, and makes more sense from the name of your function.
function returnLargestArray(a, b) {
return 'winner is ' + (a.length == b.length ? 'nobody' : (a.length > b.length ? a : b).name);
}
You could use a different structure in your code. Looks like you need objects with two properties: A name and an array of data.
var logA = {
name: "logA",
array: [8, 7, 5, 4, 6, 8, 0, 9, 4]
};
var logB = {
name: "logB",
array: [1, 5, 4, 6, 5, 9, 3, 2, 7, 3, 2]
};
Then define a function operating on such objects:
function largestLog( a, b ) {
if ( a.array.length > b.array.length ) {
return a;
}
else {
return b;
}
}
And then you can call the function, get the object with largest array, and print its name to console:
var l = largestLog( logA, logB );
console.log( l.name );
In normal circumstances you would probably check the length of the arrays and then return the one that satisfied the logic (larger or smaller) then work with that object.
The reassignment of a and b, to arrayA and arrayB seems to have no merit, other that to give a semantic answer. You may as well use those var assignments as strings as it would make more sense in the context your are demonstrating.
var arrayLogA = [8, 7, 5, 4, 6, 8, 0, 9, 4];
var arrayLogB = [1, 5, 4, 6, 5, 9, 3, 2, 7, 3, 2]
function returnLargestArray(a, b) {
var a = a.length,
b = b.length,
winner = 'arrayA';
if(a < b && a !== b) {
winner = 'arrayB';
} else {
winner = 'none';
}
return winner;
}
returnLargestArray(arrayLogA, arrayLogB);
Math.max() is probably surplus to requirements, I wouldn't imagine it has any speed advantages over normal operators [=!<>] seeing as you are bringing another object in to play Math and accessing a function of that object.
The way I have been taught is (in this binary scenario [true, false] [a or b] etc) is to set a return value at the top of the function. This way everyone who reads can easily see what the functions purpose is, then use your logic to switch that state.
So if winner = a; you test is b larger than a, if it is, set winner = b. Saves a lot of code and should be more efficient.

Categories

Resources