Determine which array is lengthier JavaScript - 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.

Related

Can you sort positive integers in O(N) (linear) time using an object in JavaScript?

I need to sort an array of positive integers.
It's easy enough to do via JavaScript's sort method in O(N * log(N)):
let a = [4, 1, 3, 9, 7, 19, 11];
a.sort((a,b) => a - b);
return a;
// returns [1, 3, 4, 7, 9, 11, 19]
But, it seems like it can be done in O(N) using a JavaScript object?
Looping through the array to add an integer into an object is O(N), then grabbing the values from that object is also O(N). (Alternatively, grab the keys and convert back to numbers).
let o = {};
let a = [4, 1, 3, 9, 7, 19, 11];
a.forEach(integer => { o[integer] = integer });
return Object.values(o);
// returns [1, 3, 4, 7, 9, 11, 19]
Drop the constant and we're looking at sorting positive integers in O(N) (sacrificing additional O(N) space).
From everything I've read, this shouldn't be possible. What am I missing here?
The internal code used for setting and retrieving keys is implementation-dependent. The output (and order) is guaranteed (for all property enumeration methods, as of ES2020), but the mechanism is up to the implementer. You'd have to look at the engine source code for that.
I don't know the code that the different Javascript engines are running under the hood, but if you know of an upper bound on the number in the array, this is possible in O(n) (or, more precisely, O(n + k) where k is a constant - the upper bound) by using counting sort: create a map of the keys (similar to you're doing, but including the number of times each item appears), then iterate from 0 to the upper bound, checking to see if the number being iterated over is included in the keys. If so, push to the array:
let o = {};
let a = [4, 1, 3, 9, 7, 19, 11];
// O(n)
for (const num of a) {
if (!o[num]) {
o[num] = [];
}
o[num].push(num);
}
// O(n). This part isn't strictly necessary, but the alternative makes the code uglier
const max = Math.max(...a);
const result = [];
// O(k)
for (let i = 0; i <= max; i++) {
if (o[i]) {
// total of O(n) items pushed over the whole loop
result.push(...o[i]);
}
}
console.log(result);
If, like in your example, there are no repeated numbers, the code is significantly easier:
let o = {};
let a = [4, 1, 3, 9, 7, 19, 11];
for (const num of a) {
o[num] = true;
}
// O(n)
const max = Math.max(...a);
const result = [];
// O(k)
for (let i = 0; i <= max; i++) {
if (o[i]) {
// total of O(n) items pushed over the whole loop
result.push(i);
}
}
console.log(result);

How do I reduce two arrays to a single value that is present at the same index?

I have a D3 programme that is building a line chart where there are two lines and I want to ascertain the coordinates at where the lines cross . Does D3 have a function for this? The arrays are often of differing lengths and are dynamically generated, but will always have one value at which both will be equal at the same index.
e.g.
var line1 = [0,1,2,3,4];
var line2 = [4,3,2,1,0];
Answer = index 2, in this case. If there is no D3 function for this what would be the best approach using ES6 and above?
D3 has a quite unknown method, named d3.zip, which we can use to merge the arrays and look for any inner array in which all the elements are equal:
var line1 = [0, 1, 2, 3, 4];
var line2 = [4, 3, 2, 1, 0];
var zip = d3.zip(line1, line2).reduce(function(a, c, i) {
if (c[0] === c[1]) a.push(i);
return a;
}, []);
console.log(zip)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
The nice thing about d3.zip is that it can be used with several arrays, and also keeps the length of the shorter array. So, in a more complex case (equal values in the indices 6 and 9):
var line1 = [0, 1, 2, 3, 9, 9, 1, 4, 7, 6, 5, 4];
var line2 = [4, 3, 2, 1, 0, 8, 1, 2, 3, 6, 1];
var line3 = [9, 9, 9, 9, 4, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1];
var zip = d3.zip(line1, line2, line3).reduce(function(a, c, i) {
const every = c.every(function(e) {
return e === c[0]
})
if (every) a.push(i);
return a;
}, []);
console.log(zip)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
const [longer, shorter] = line1.length > line2.length ? [line1, line2] : [line2, line1];
const crossIndex = shorter.reduce((crossIndex, value, index) => {
if (crossIndex !== null) {
// already found it! just return
return crossIndex;
}
// find it! return
if (value === longer[index]) return index;
// no found, continue searching
return crossIndex;
}, null)
If you don't mind the search running a few extra useless iterations, the first step where we find out which line is longer or shorter, is actually not necessary. You call .reduce() on either line1 or line 2, then compare again the other, you'll still get the same result.

Javascript have a function return no value

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, []);

Merging of two arrays, store unique elements, and sorting in jQuery

var Arr1 = [1,3,4,5,6];
var Arr2 = [4,5,6,8,9,10];
I am trying to do merge these two arrays and output coming is [1,3,4,5,6,4,5,6]
I have used $.merge(Arr1, Arr2); this piece to merge them. Using alert I can see the merged array like above.
Now my question is how can I get the following output:
[1,3,4,5,6,8,9,10]
i.e. the elements should be unique as well as sorted in the same manner I have mentioned.
Please help.
You can use Array.prototype.sort() to do a real numeric sort and use Array.prototype.filter() to only return the unique elements.
You can wrap it into a helper similar to this:
var concatArraysUniqueWithSort = function (thisArray, otherArray) {
var newArray = thisArray.concat(otherArray).sort(function (a, b) {
return a > b ? 1 : a < b ? -1 : 0;
});
return newArray.filter(function (item, index) {
return newArray.indexOf(item) === index;
});
};
Note that the custom sort function works with numeric elements only, so if you want to use it for strings or mix strings with numbers you have to update it off course to take those scenarios into account, though the rest should not change much.
Use it like this:
var arr1 = [1, 3, 4, 5, 6];
var arr2 = [4, 5, 6, 8, 9, 10];
var arrAll = concatArraysUniqueWithSort(arr1, arr2);
arrAll will now be [1, 3, 4, 5, 6, 8, 9, 10]
DEMO - concatenate 2 arrays, sort and remove duplicates
There is many ways of doing this I'm sure. This was just the most concise I could think off.
merge two or more arrays + remove duplicities + sort()
jQuery.unique([].concat.apply([],[[1,2,3,4],[1,2,3,4,5,6],[3,4,5,6,7,8]])).sort();
One line solution using just javascript.
var Arr1 = [1,3,4,5,6];
var Arr2 = [4,5,6,8,9,10];
const sortedUnion = [... new Set([...Arr1,... Arr2].sort((a,b)=> a-b))]
console.log(sortedUnion)
This looks like a job for Array.prototype.indexOf
var arr3 = arr1.slice(), // clone arr1 so no side-effects
i; // var i so it 's not global
for (i = 0; i < arr2.length; ++i) // loop over arr2
if (arr1.indexOf(arr2[i]) === -1) // see if item from arr2 is in arr1 or not
arr3.push(arr2[i]); // it's not, add it to arr3
arr3.sort(function (a, b) {return a - b;});
arr3; // [1, 3, 4, 5, 6, 8, 9, 10]
a = [1, 2, 3]
b = [2, 3, 4]
$.unique($.merge(a, b)).sort(function(a,b){return a-b}); -> [1, 2, 3, 4]
Update:
This is a bad idea, since the 'unique' function is not meant for use on numbers or strings.
However, if you must then the sort function needs to be told to use a new comparator since by default it sorts lexicographically.
Using underscore.js:
_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]).sort(function(a,b){return a-b});
=> [1, 2, 3, 10, 101]
This example is taken directly from underscore.js, a popular JS library which complements jQuery
I did that as follows, where t1 and t2 are my two tables.
The first command put the values of the table t2 to the t1. The second command removes the duplicate values from the table.
$.merge(t1, t2);
$.unique(t1);
function sortUnique(matrix) {
if(matrix.length < 1 || matrix[0].length < 1) return [];
const result = [];
let temp, ele;
while(matrix.length > 0) {
temp = 0;
for(let j=0; j<matrix.length; j++) {
if(matrix[j][0] < matrix[temp][0]) temp = j;
}
if(result.length === 0 || matrix[temp][0] > result[result.length-1]) {
result.push(matrix[temp].splice(0,1)[0]);
} else {
matrix[temp].splice(0,1);
}
if(matrix[temp].length===0) matrix.splice(temp, 1);
}
return result;
}
console.log(sortUnique([[1,4,8], [2,4,9], [1,2,7]]))
Using JavaScript ES6 makes it easier and cleaner. Try this:
return [...Arr1, ...Arr2].filter((v,i,s) => s.indexOf(v) === i).sort((a,b)=> a - b);
and there you have it. You could build it in a function like:
function mergeUniqueSort(Arr1, Arr2){
return [...Arr1, ...Arr2].filter((v,i,s) => s.indexOf(v) === i).sort((a,b)=> a - b);
}
and that settles it. You can also break it down using ES6. Use a Spread Operator to combine arrays:
let combinedArrays = [...Arr1, ...Arr2]
then get the unique elements using the filter function:
let uniqueValues = combinedArrays.filter((value, index, self ) => self.indexOf(value) === index)
Lastly you now sort the uniqueValue object:
let sortAscending = uniqueValues.sort((a-b) => a - b) // 1, 2, 3, ....10
let sortDescending = uniqueValues.sort((b-a) => b - a) // 10, 9, 8, ....1
So you could use any part, just in case.

How to count certain elements in array?

I have an array:
[1, 2, 3, 5, 2, 8, 9, 2]
I would like to know how many 2s are in the array.
What is the most elegant way to do it in JavaScript without looping with for loop?
[this answer is a bit dated: read the edits, in the notion of 'equal' in javascript is ambiguous]
Say hello to your friends: map and filter and reduce and forEach and every etc.
(I only occasionally write for-loops in javascript, because of block-level scoping is missing, so you have to use a function as the body of the loop anyway if you need to capture or clone your iteration index or value. For-loops are more efficient generally, but sometimes you need a closure.)
The most readable way:
[....].filter(x => x==2).length
(We could have written .filter(function(x){return x==2}).length instead)
The following is more space-efficient (O(1) rather than O(N)), but I'm not sure how much of a benefit/penalty you might pay in terms of time (not more than a constant factor since you visit each element exactly once):
[....].reduce((total,x) => (x==2 ? total+1 : total), 0)
or as a commenter kindly pointed out:
[....].reduce((total,x) => total+(x==2), 0)
(If you need to optimize this particular piece of code, a for loop might be faster on some browsers... you can test things on jsperf.com.)
You can then be elegant and turn it into a prototype function:
[1, 2, 3, 5, 2, 8, 9, 2].count(2)
Like this:
Object.defineProperties(Array.prototype, {
count: {
value: function(value) {
return this.filter(x => x==value).length;
}
}
});
You can also stick the regular old for-loop technique (see other answers) inside the above property definition (again, that would likely be much faster).
2017 edit:
Whoops, this answer has gotten more popular than the correct answer. Actually, just use the accepted answer. While this answer may be cute, the js compilers probably don't (or can't due to spec) optimize such cases. So you should really write a simple for loop:
Object.defineProperties(Array.prototype, {
count: {
value: function(query) {
/*
Counts number of occurrences of query in array, an integer >= 0
Uses the javascript == notion of equality.
*/
var count = 0;
for(let i=0; i<this.length; i++)
if (this[i]==query)
count++;
return count;
}
}
});
You could define a version .countStrictEq(...) which used the === notion of equality. The notion of equality may be important to what you're doing! (for example [1,10,3,'10'].count(10)==2, because numbers like '4'==4 in javascript... hence calling it .countEq or .countNonstrict stresses it uses the == operator.)
Caveat:
Defining a common name on the prototype should be done with care. It is fine if you control your code, but bad if everyone wants to declare their own [].count function, especially if they behave differently. You may ask yourself "but .count(query) surely sounds quite perfect and canonical"... but consider perhaps you could do something like [].count(x=> someExpr of x). In that case you define functions like countIn(query, container) (under myModuleName.countIn), or something, or [].myModuleName_count().
Also consider using your own multiset data structure (e.g. like python's 'collections.Counter') to avoid having to do the counting in the first place. This works for exact matches of the form [].filter(x=> x==???).length (worst case O(N) down to O(1)), and modified will speed up queries of the form [].filter(filterFunction).length (roughly by a factor of #total/#duplicates).
class Multiset extends Map {
constructor(...args) {
super(...args);
}
add(elem) {
if (!this.has(elem))
this.set(elem, 1);
else
this.set(elem, this.get(elem)+1);
}
remove(elem) {
var count = this.has(elem) ? this.get(elem) : 0;
if (count>1) {
this.set(elem, count-1);
} else if (count==1) {
this.delete(elem);
} else if (count==0)
throw `tried to remove element ${elem} of type ${typeof elem} from Multiset, but does not exist in Multiset (count is 0 and cannot go negative)`;
// alternatively do nothing {}
}
}
Demo:
> counts = new Multiset([['a',1],['b',3]])
Map(2) {"a" => 1, "b" => 3}
> counts.add('c')
> counts
Map(3) {"a" => 1, "b" => 3, "c" => 1}
> counts.remove('a')
> counts
Map(2) {"b" => 3, "c" => 1}
> counts.remove('a')
Uncaught tried to remove element a of type string from Multiset, but does not exist in Multiset (count is 0 and cannot go negative)
sidenote: Though, if you still wanted the functional-programming way (or a throwaway one-liner without overriding Array.prototype), you could write it more tersely nowadays as [...].filter(x => x==2).length. If you care about performance, note that while this is asymptotically the same performance as the for-loop (O(N) time), it may require O(N) extra memory (instead of O(1) memory) because it will almost certainly generate an intermediate array and then count the elements of that intermediate array.
Modern JavaScript:
Note that you should always use triple equals === when doing comparison in JavaScript (JS). The triple equals make sure, that JS comparison behaves like double equals == in other languages (there is one exception, see below). The following solution shows how to solve this the functional way, which will ensure that you will never have out of bounds error:
// Let has local scope
let array = [1, 2, 3, 5, 2, 8, 9, 2]
// Functional filter with an Arrow function
// Filter all elements equal to 2 and return the length (count)
array.filter(x => x === 2).length // -> 3
The following anonymous Arrow function (lambda function) in JavaScript:
(x) => {
const k = 2
return k * x
}
may be simplified to this concise form for a single input:
x => 2 * x
where the return is implied.
Always use triple equals: === for comparison in JS, with the exception of when checking for nullability: if (something == null) {} as it includes a check for undefined, if you only use double equals as in this case.
Very simple:
var count = 0;
for(var i = 0; i < array.length; ++i){
if(array[i] == 2)
count++;
}
2017:
If someone is still interested in the question, my solution is the following:
const arrayToCount = [1, 2, 3, 5, 2, 8, 9, 2];
const result = arrayToCount.filter(i => i === 2).length;
console.log('number of the found elements: ' + result);
Here is an ES2017+ way to get the counts for all array items in O(N):
const arr = [1, 2, 3, 5, 2, 8, 9, 2];
const counts = {};
arr.forEach((el) => {
counts[el] = counts[el] ? (counts[el] + 1) : 1;
});
You can also optionally sort the output:
const countsSorted = Object.entries(counts).sort(([_, a], [__, b]) => a - b);
console.log(countsSorted) for your example array:
[
[ '2', 3 ],
[ '1', 1 ],
[ '3', 1 ],
[ '5', 1 ],
[ '8', 1 ],
[ '9', 1 ]
]
If you are using lodash or underscore the _.countBy method will provide an object of aggregate totals keyed by each value in the array. You can turn this into a one-liner if you only need to count one value:
_.countBy(['foo', 'foo', 'bar'])['foo']; // 2
This also works fine on arrays of numbers. The one-liner for your example would be:
_.countBy([1, 2, 3, 5, 2, 8, 9, 2])[2]; // 3
Weirdest way I can think of doing this is:
(a.length-(' '+a.join(' ')+' ').split(' '+n+' ').join(' ').match(/ /g).length)+1
Where:
a is the array
n is the number to count in the array
My suggestion, use a while or for loop ;-)
Not using a loop usually means handing the process over to some method that does use a loop.
Here is a way our loop hating coder can satisfy his loathing, at a price:
var a=[1, 2, 3, 5, 2, 8, 9, 2];
alert(String(a).replace(/[^2]+/g,'').length);
/* returned value: (Number)
3
*/
You can also repeatedly call indexOf, if it is available as an array method, and move the search pointer each time.
This does not create a new array, and the loop is faster than a forEach or filter.
It could make a difference if you have a million members to look at.
function countItems(arr, what){
var count= 0, i;
while((i= arr.indexOf(what, i))!= -1){
++count;
++i;
}
return count
}
countItems(a,2)
/* returned value: (Number)
3
*/
I'm a begin fan of js array's reduce function.
const myArray =[1, 2, 3, 5, 2, 8, 9, 2];
const count = myArray.reduce((count, num) => num === 2 ? count + 1 : count, 0)
In fact if you really want to get fancy you can create a count function on the Array prototype. Then you can reuse it.
Array.prototype.count = function(filterMethod) {
return this.reduce((count, item) => filterMethod(item)? count + 1 : count, 0);
}
Then do
const myArray =[1, 2, 3, 5, 2, 8, 9, 2]
const count = myArray.count(x => x==2)
Most of the posted solutions using array functions such as filter are incomplete because they aren't parameterized.
Here goes a solution with which the element to count can be set at run time.
function elementsCount(elementToFind, total, number){
return total += number==elementToFind;
}
var ar = [1, 2, 3, 5, 2, 8, 9, 2];
var elementToFind=2;
var result = ar.reduce(elementsCount.bind(this, elementToFind), 0);
The advantage of this approach is that could easily change the function to count for instance the number of elements greater than X.
You may also declare the reduce function inline
var ar = [1, 2, 3, 5, 2, 8, 9, 2];
var elementToFind=2;
var result = ar.reduce(function (elementToFind, total, number){
return total += number==elementToFind;
}.bind(this, elementToFind), 0);
Really, why would you need map or filter for this?
reduce was "born" for these kind of operations:
[1, 2, 3, 5, 2, 8, 9, 2].reduce( (count,2)=>count+(item==val), 0);
that's it! (if item==val in each iteration, then 1 will be added to the accumulator count, as true will resolve to 1).
As a function:
function countInArray(arr, val) {
return arr.reduce((count,item)=>count+(item==val),0)
}
Or, go ahead and extend your arrays:
Array.prototype.count = function(val) {
return this.reduce((count,item)=>count+(item==val),0)
}
It is better to wrap it into function:
let countNumber = (array,specificNumber) => {
return array.filter(n => n == specificNumber).length
}
countNumber([1,2,3,4,5],3) // returns 1
I use this:
function countElement(array, element) {
let tot = 0;
for(var el of array) {
if(el == element) {
tot++;
}
}
return tot;
}
var arr = ["a", "b", "a", "c", "d", "a", "e", "f", "a"];
console.log(countElement(arr, "a")); // 4
var arrayCount = [1,2,3,2,5,6,2,8];
var co = 0;
function findElement(){
arrayCount.find(function(value, index) {
if(value == 2)
co++;
});
console.log( 'found' + ' ' + co + ' element with value 2');
}
I would do something like that:
var arrayCount = [1,2,3,4,5,6,7,8];
function countarr(){
var dd = 0;
arrayCount.forEach( function(s){
dd++;
});
console.log(dd);
}
I believe what you are looking for is functional approach
const arr = ['a', 'a', 'b', 'g', 'a', 'e'];
const count = arr.filter(elem => elem === 'a').length;
console.log(count); // Prints 3
elem === 'a' is the condition, replace it with your own.
Array.prototype.count = function (v) {
var c = 0;
for (let i = 0; i < this.length; i++) {
if(this[i] === v){
c++;
}
}
return c;
}
var arr = [1, 2, 3, 5, 2, 8, 9, 2];
console.log(arr.count(2)); //3
Solution by recursion
function count(arr, value) {
if (arr.length === 1) {
return arr[0] === value ? 1 : 0;
} else {
return (arr.shift() === value ? 1 : 0) + count(arr, value);
}
}
count([1,2,2,3,4,5,2], 2); // 3
Create a new method for Array class in core level file and use it all over your project.
// say in app.js
Array.prototype.occurrence = function(val) {
return this.filter(e => e === val).length;
}
Use this anywhere in your project -
[1, 2, 4, 5, 2, 7, 2, 9].occurrence(2);
// above line returns 3
Here is a one liner in javascript.
Use map. Find the matching values (v === 2) in the array, returning an array of ones and zeros.
Use Reduce. Add all the values of the array for the total number found.
[1, 2, 3, 5, 2, 8, 9, 2]
.map(function(v) {
return v === 2 ? 1 : 0;
})
.reduce((a, b) => a + b, 0);
The result is 3.
Depending on how you want to run it:
const reduced = (array, val) => { // self explanatory
return array.filter((element) => element === val).length;
}
console.log(reduced([1, 2, 3, 5, 2, 8, 9, 2], 2));
// 3
const reducer = (array) => { // array to set > set.forEach > map.set
const count = new Map();
const values = new Set(array);
values.forEach((element)=> {
count.set(element, array.filter((arrayElement) => arrayElement === element).length);
});
return count;
}
console.log(reducer([1, 2, 3, 5, 2, 8, 9, 2]));
// Map(6) {1 => 1, 2 => 3, 3 => 1, 5 => 1, 8 => 1, …}
You can use built-in function Array.filter()
array.filter(x => x === element).length;
var arr = [1, 2, 3, 5, 2, 8, 9, 2];
// Count how many 2 there are in arr
var count = arr.filter(x => x === 2).length;
console.log(count);
One-liner function
const countBy = (a,f)=>a.reduce((p,v,i,x)=>p+!!f(v,i,x), 0)
countBy([1,2,3,4,5], v=>v%2===0) // 2
There are many ways to find out. I think the easiest way is to use the array filter method which is introduced in es6.
function itemCount(array, item) {
return array.filter(element => element === item).length
}
const myArray = [1,3,5,7,1,2,3,4,5,1,9,0,1]
const items = itemCount(myArray, 1)
console.log(items)
Something a little more generic and modern (in 2022):
import {pipe, count} from 'iter-ops';
const arr = [1, 2, 3, 5, 2, 8, 9, 2];
const n = pipe(arr, count(a => a === 2)).first; //=> 3
What's good about this:
It counts without creating a new array, so it is memory-efficient
It works the same for any Iterable and AsyncIterable
Another approach using RegExp
const list = [1, 2, 3, 5, 2, 8, 9, 2]
const d = 2;
const counter = (`${list.join()},`.match(new RegExp(`${d}\\,`, 'g')) || []).length
console.log(counter)
The Steps follows as below
Join the string using a comma Remember to append ',' after joining so as not to have incorrect values when value to be matched is at the end of the array
Match the number of occurrence of a combination between the digit and comma
Get length of matched items
I believe you can use the new Set array method of JavaScript to have unique values.
Example:
var arr = [1, 2, 3, 5, 2, 8, 9, 2]
var set = new Set(arr);
console.log(set);
// 1,2,3,5,8,9 . We get unique values as output.
You can use length property in JavaScript array:
var myarray = [];
var count = myarray.length;//return 0
myarray = [1,2];
count = myarray.length;//return 2

Categories

Resources