JavaScript Jest Testing; Using Callback Function to Modify Elements in Array - javascript

I'm using the Jest testing library to test a function that invokes a callback that takes two parameters, element[i], and i.
Here is the function I am to test:
const each = (elements, cb) => {
for (let i = 0; i < elements.length; i++) {
cb(elements[i], i);
}
};
I know the array will only have numbers, so in the testing function I'm trying to make the callback simply add the index to each number in the array; e.g., it should change an array of [1, 2, 3, 4] to [1, 3, 5, 7].
Here is what I tried to do:
const arrayFunctions = require('./arrays');
describe('Arrays', () => {
it('each', () => {
const callBack = (elem, indx) => {
elem += indx;
}
const arr = [1, 2, 3, 4];
arrayFunctions.each(arr, callBack);
expect(arr).toEqual([1, 3, 5, 7]);
})
});
And here is the error I'm getting:
Received:
[1, 2, 3, 4]
Difference:
- Expected
+ Received
Array [
1,
+ 2,
3,
- 5,
- 7,
+ 4,
]
15 | const arr = [1, 2, 3, 4];
16 | arrayFunctions.each(arr, callBack);
> 17 | expect(arr).toEqual([1, 3, 5, 7]);
| ^
18 | })
19 | });
20 |
at Object.it (advanced-javascript/arrays.spec.js:17:21)
Why is it not modifying the array as expected? To reiterate with an even simpler example, why does this work:
const arr = [1, 2, 3, 4];
for (let i = 0; i < arr.length; i++) {
arr[i] += i;
}
console.log(arr) // [1, 3, 5, 7];
While this doesn't?
const arr = [1, 2, 3, 4];
each(arr, callBack);
console.log(arr); // [1, 2, 3, 4];

The difference is because of a subtlety of index assignment. It looks like two operators ([n] and +=) but it is actually one: [n]+=. In the end using += (add and assign) is not the same as [n] += (add and assign to value at index), so you can put spaces between the index and the assignment characters (and strangely, even parentheses, but that's just confusing), but you can't split it into separate statement lines, which is effectively what you are doing (see below).
Let's make our own array and look at how we would implement [n] (let's call it get(n)) and [n]=value (let's call that function set(n, value). For ease of readability, I'll use the new class syntax.
class FakeArray {
get(index) {
var valueAtIndex = // somehow get that value
return valueAtIndex
}
set(index, value) {
//somehow set that value
}
}
Now think about if you could implement set using get. Would this work?:
set(index, value) {
this.get(index) = value
}
It wouldn't. You would get an error: ReferenceError: Left side of assignment is not a reference. (you can change the values of references, but not the values of values). However, if you could, you wouldn't really need the set function. You could just use the get function combined with = (and also +=, -=, etc.). But you can't split them up, so they are completely different functions / operators. It's the same with [n] and [n]=. They work entirely different, they aren't combinations of the two.
Also, when you pass values to a function, you are essentially assigning them to a new variable:
var a = 1;
function foo (b) {
b = b + 1
console.log(b)
};
foo(a)
console.log(a)
is mostly equivalent to:
var a = 1;
var b = a
b = b + 1
console.log(b)
console.log(a)
This is called pass by value, and it is the only way to pass values in javascript. See this answer for more detail: What's the difference between passing by reference vs. passing by value?

Related

javascript map function returned undefined

const numbers = [1, 2, 3, 4];
const filteredNumbers = numbers.map((num, index) => {
if (index < 3) {
return num;
}
});
// filteredNumbers is [1, 2, 3, undefined]
According to my understanding callback function should return all numbers of array if their index is less than 3 so it should return 1,2,3 and stop after that and number 4 can not be returned as if condition says index should be less than 3.
I am wondering why it returned undefined for index 3 number.
.map is an isomorphism and preserves the length of the given array.
So if the callback function does not return anything, the index will be undefined.
You want to user a filter function instead if you need to filter array elements that meet a certain condition.
const numbers = [1, 2, 3, 4];
const filteredNumbers = numbers.filter((_, index) => index < 3);
console.log(filteredNumbers);
If you want just to get the first 3 items in the array, I recommend using slice.
const numbers = [1, 2, 3, 4];
console.log(numbers.slice(0, 3));
Second solution is use filter instead of map.
const numbers = [1, 2, 3, 4];
const filteredNumbers = numbers.filter((num, index) => {
return index < 3
});
console.log(filteredNumbers)

Is this considered a selection sort?

I was practicing a while ago and came across selection sort. After some research across difference sources, there are some that declare an array then delete the current min location while others swap within the array
I tried to use ES6 for some trivial functions, did not use map since I wanted to understand the loop on a whiteboard.
Is this considered a selection sort?
selectionSortNoSwap = list)= => {
const result = [];
for (let i = 0; i < list; i++) {
const min = Math.min(...list);
const minIndex = list.indexOf(min);
result.push(min);
list.splice(minIndex, 1);
}
return result;
};
selectionSortNoSwap([3, 5, 2, 1, 4]);
Thank you
No. True selection sort sorts in-place, rather than creating another array. That is, given:
[3, 5, 2, 1, 4]
after the first iteration, a selection sort should produce the following data structure in memory:
[1, 5, 2, 3, 4]
where the 1 and 3 have been exchanged - and not
[3, 5, 2, 4]
[1]
If elements are not swapped with each other, it's not selection sort.
To sort in-place, you'd need something like
const selectionSort = (list) => {
for (let i = 0; i < list.length; i++) {
// for convenience - or use a for loop
const min = Math.min(...list.slice(i));
const minIndex = list.indexOf(min, i);
[list[i], list[minIndex]] = [list[minIndex], list[i]];
}
return list;
};
console.log(selectionSort([3, 5, 2, 1, 4]));

Use Array.length property and not a function to return length of an array by counting only distinct elements and not all elements

So I have an array like this:
items = [2, 2, 5, 3, 5, 3, 4, 7, 2, 7];
Is there a way to use items.length property here to return 5 instead of 10. I have seen a method where a function was used to get the count of the distinct elements by passing the length property as an argument. What I want to achieve is slightly different. I want the length to be printed by calling the Array.length property instead of through a function. Is it possible at all?
Here is the function:
function countDistinct(arr, n) {
let res = 1;
// Pick all elements one by one
for (let i = 1; i < n; i++) {
let j = 0;
for (j = 0; j < i; j++)
if (arr[i] === arr[j])
break;
// If not printed earlier, then print it
if (i === j)
res++;
}
return res;
}
// Driver program to test above function
let arr = [2, 2, 5, 3, 5, 3, 4, 7, 2, 7];
let n = arr.length;
console.log((countDistinct(arr, n)));
This is barely possible, but it's really weird. If you create another object that wraps the array, you can make the length property a getter that deduplicates items and returns the size, something along the lines of:
const makeSpecialArr = (arr) => {
const specialArr = Object.create(arr);
Object.defineProperty(specialArr, 'length', {
get() {
return new Set(arr).size;
},
});
return specialArr;
};
const arr = makeSpecialArr([2, 2, 5, 3, 5, 3, 4, 7, 2, 7]);
console.log(arr.length);
You can't do this without creating another object around the array because an array's .length is an own non-configurable property.
If you wanted to do something like this, consider using a property other than length, which makes it a lot easier:
const makeSpecialArr = (arr) => {
Object.defineProperty(arr, 'dedupLength', { get() {
return new Set(arr).size;
}});
return arr;
};
const arr = makeSpecialArr([2, 2, 5, 3, 5, 3, 4, 7, 2, 7]);
console.log(arr.dedupLength);
But even this is strange. Might be interesting as theoretical code, or for a thought experiment, but I wouldn't use it for anything serious that had to be maintained.
You can use reduce for this:
var count = arr.reduce(function(values, v) {
if (!values.set[v]) {
values.set[v] = 1;
values.count++;
}
return values;
}, { set: {}, count: 0 }).count;

Order an unordered array of numbers from 1-8, so that the end and starting integers are alternated eg [8,1,7,2,6,3,5,4,]

I'm a newbie to all of this and trying to improve myself by solving problems and challenges.
I came across a problem whereby I have an unordered array which contains 8 integers.
eg [2,3,1,4,6,5,8,7]
I need to sort it [1,2,3,4,5,6,7,8] and reorder the array so that the array starts with the end value and then the first value and so on eg [8,1,7,2,6,3,5,4,]
I worked out I could use map() to iterate across the array and then use push() with pop() and shift() however it leaves the last 2 numbers behind in the original array and I'm not sure why. I got around this by using a concat and a reverse but I still don't understand why pop and shift don't bring across all the elements.
Code below that doesn't pull all the elements:
const reorder = (array) => {
let store = []
array.sort((a, b) => a - b).map((item, i) => {
if (array) {
store.push(array.pop())
store.push(array.shift())
}
})
return store
}
reorder([2, 3, 1, 4, 6, 5, 8, 7]) // returns [8,1,7,2,6,3]
Code that works but I have to add a concat and a reverse:
const reorder = (array) => {
let store = []
array.sort((a, b) => a - b).map((item, i) => {
if (array) {
store.push(array.pop())
store.push(array.shift())
}
})
return store.concat(array.reverse())
}
reorder([2, 3, 1, 4, 6, 5, 8, 7]) //returns [8,1,7,2,6,3,5,4]
Thanks for any help
I would just bisect the array, sort them in opposite orders and then add each element from each array to a new array
Given that you want to then take the sorted bisected arrays and produce another single array, I'd then use Array.prototype.reduce:
const alternatingSort = function (array) {
array = array.sort();
const midpoint = Math.round(array.length / 2)
let arr1 = array.slice(0, midpoint);
let arr2 = array.slice(midpoint);
arr2 = arr2.sort(function (a, b) { return b - a });
return arr1.reduce(function (retVal, item, index) {
arr2[index] && retVal.push(arr2[index]);
retVal.push(item);
return retVal;
}, []);
}
console.log(alternatingSort([2, 3, 1, 4, 6, 5, 8, 7]));
console.log(alternatingSort([2, 3, 1, 4, 6, 5, 8])); // with odd number
As I've seen nobody explained why the original OP solution doesn't work, Here is why:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/
Map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values (including undefined).
It is not called for missing elements of the array; that is:
1.Indexes that have never been set;
2.which have been deleted; or
3.which have never been assigned a value.
So what is happening in our code is that:
On the first iteration,
[(2), 3, 1, 4, 6, 5, 8, 7]
Map picks the first element(2) in the array, and delete the first and last characters in the array, so the array becomes
[3,(1), 4, 6, 5, 8]
Now, as map will not consider deleted elements, the second element(1) in the current array is called, also the first and last element in also removed:
[1, 4,(6), 5]
Now, map is trying to find the third element(6), and delete the first and last element:
[4,6]
Now, map is trying to find the fourth element, which is out of bound, so the map function will terminate.
So, you are strongly advised not to use Array.prototype.shift or Array.prototype.pop in Array.prototype.map.
You can do it following way:
const reorder = (array) => {
array.sort((a, b) => a - b);
const result = [];
const length = array.length;
for (let i = 0; i < length; i++) {
if (i % 2 === 0) {
result.push(array.pop());
} else {
result.push(array.shift());
}
}
return result;
}
const result = reorder([2, 3, 1, 4, 6, 5, 7]);
console.log(result);
Notice that I've intentionally made the array length to be an odd number. Some of the solutions here will break if the length is an odd number.
Personally I would sort, split in half and then just insert in. Not very fancy, but gets the job done.
function strangeWeave (arr) {
var sorted = arr.slice().sort()
var result = sorted.splice(0,Math.floor(sorted.length/2))
for (let i=0;sorted.length;i+=2) {
result.splice(i,0,sorted.pop())
}
return result
}
console.log(strangeWeave([1,2]))
console.log(strangeWeave([1,2,3]))
console.log(strangeWeave([1,2,3,4,5,6,7,8]))
console.log(strangeWeave([1,2,3,4,5,6,7,8,9]))
There is a much easier solution to sort two different arrays, one normal and one in reverse, then connect them together. Here is the code for that:
var myArray = [1, 3, 2, 4, 5, 7, 6, 8];
function getCopy(arr) {
var x = [];
for(var i = 0; i < arr.length; i++)
x.push(arr[i]);
return x;
}
function sortMyWay(arr) {
var sortedArr = [],
leftSide = getCopy(arr).sort()
.splice(0, Math.ceil(arr.length / 2)),
rightSide = getCopy(arr).sort().reverse()
.splice(0, Math.floor(arr.length / 2));
for(var i = 0; i < arr.length; i++)
i % 2
? sortedArr.push(leftSide[Math.floor(i / 2)])
: sortedArr.push(rightSide[Math.floor(i / 2)]);
console.log(sortedArr);
return sortedArr;
}
var sortedArr = sortMyWay(myArray);
Hope it helped!
Happy coding :)

counting number of occurrences in an array [duplicate]

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