I want to add only integers and ignore others in a particular array. I want to add this condition on that array's push event.
Array.prototype.push = function(){
if(condition){
//execute push if true
}
else
{
//return false
}
}
Help me how to code this? This affects all the array in my code. I want to check this condition on push only for a particular array. what are the ways to achieve it?
jsFiddle: http://jsfiddle.net/QhJzE/4
Add the method directly to the array:
var nums = [];
nums.push = function(n) {
if (isInt(n))
Array.prototype.push.call(this, n);
}
nums.push(2);
nums.push(3.14);
nums.push('dawg');
console.log(nums);
(See How do I check that a number is float or integer? for isInt function.)
Here's some great information: http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/. What I've shown here is called "direct extension" in that article.
Related
I just started learning code and i'm currently stuck on the following assignment.
Assignment:
Code a function that checks if an array contains a number by returning a boolean.(Java code)
Examples: contains([1, 2, 3, 4], 3) returns true. contains([2, 2, 4], 3) returns false.
I've tried the following:
code
Can anyone help me with solving this one?
You can use the includes() method which is available for JavaScript arrays. It will check if a specific element is included in the array and will return a boolean value of either true or false.
function contains(array, number){
var ans = array.includes(number);
return ans;
}
console.log(contains([1,2,3,4],3)); // Prints true
console.log(contains([2,2,4],3)); // Prints false
You should iterate for each array element. Considering that your array contains numbers check the following function
function contains(numberArray, check){
var i;
for (i = 0; i < numberArray.length; i++) {
if (numberArray[i] == check){
return true;
}
}
return false;
}
It takes the numberArray array as input and the check number. Then it iterates for each number in the array and checks if it finds the same number with the check number.
If it finds it, then it returns true and the loop breaks.
If it does not find it, after the loop is finished iterating all the elements of the array, then it returns false.
An array is a collection of elements of a specific type. Your function takes two parameters: the array in which you want to search, and the number you want to search.
To achieve this, you have to iterate through the array, using a controlled iteration like a for loop. The loop takes all elements in the array one by one, and performs an action that you define in the loop body, in your case you can compare the current array element to the one passed to your function. If they are the same, you can return from the loop using the return statement. If all elements were
Assuming that you're using JavaScript, you'd do something like this using the for statement:
function contains(array, number){
for(var currentElementIndex in array) {
if(array[currentElementIndex] === number) {
return true;
}
}
return false;
}
I am new to JS and was trying to learn how to properly work with indexOf in JS, that is, if you look at the code below:
var sandwiches = ['turkey', 'ham', 'turkey', 'tuna', 'pb&j', 'ham', 'turkey', 'tuna'];
var deduped = sandwiches.filter(function (sandwich, index) {
return sandwiches.indexOf(sandwich) === index;
});
// Logs ["turkey", "ham", "tuna", "pb&j"]
console.log(deduped);
I am trying to remove duplicates but wanted to ask two questions. Firstly, in here return sandwiches.indexOf(sandwich) === index; why we need to use "== index;". Secondly, since indexOf returns index like 0, 1 or 2 ... then why when we console.log(deduped) we get array of names instead of array of indexes. Hope you got my points
You use a method of Javascript Array that is filter, this method take a function that returns a boolean.
The function filter returns a new Array based on the function passed applied to each entry.
If the function return true, then the entry is included in the new Array, otherwise is discarded.
As the functions check the indexOf an entry to be the current index is true for the first occurrency of the entry.
All the duplications will fail the expression as they are not the first index found by indexOf, so they are discarded.
since the logic is to remove the duplicates from the array,
in your example, you have "turkey" as duplicates.
the "turkey" exists in position 0,2,6
so whenever you call indexOf("turkey") always returns 0 because the indexOf function returns the first occurrence of a substring.
so for the elements in position 2 & 6 the condition fails. then it won't return that element.
That is how the filter works in javascript. it evaluates the condition and returns true or false that indicates whether an element to be included in the new array or not, in your example the condition is return sandwiches.indexOf(sandwich) === index;
Perhaps the basic logic is easier to see at a glance if you use arrow notation:
const deduped = myArray => myArray.filter((x, i) => myArray.indexOf(x) === i);
The key point is that indexOf returns the index of the first occurrence of x. For that occurrence the result of the comparison will be true hence the element will be retained by the filter. For any subsequent occurrence the comparison will be false and the filter will reject it.
Difference between === (identity) and == (equality): if type of compared values are different then === will return false, while == will try to convert values to the same type. So, in cases where you compare some values with known types it is better to use ===. (http://www.c-point.com/javascript_tutorial/jsgrpComparison.htm)
You get as result an array of names instead of array of indexes because Array.filter do not change the values, but only filter them. The filter function in your case is return sandwiches.indexOf(sandwich) === index; which return true or false. If you want get the indexes of your items after deduplication, then use map after filter:
a.filter(...).map(function(item, idx) {return idx;})
#Dikens, indexOf gives the index of the element if found. And if the element is not found then it returns -1.
In your case you are filtering the array and storing the values in the deduped. That's why it is showing an array.
If you console the indexOf in the filter function then it will log the index of the element.
For example :
var deduped = sandwiches.filter(function (sandwich, index) {
console.log(sandwiches.indexOf(sandwich));
return sandwiches.indexOf(sandwich) === index;
});
I am using mocha and chai for the first time and have no idea what is going on? im trying to say that my shuffle method has moved the array objects around and the first array object no longer - "sam1" IE -
describe('Shuffle', function(){
it('Shuffle should randomly move array items by their index', function(){
let group = ["sam1","sam2","sam3","sam4","sam5","sam6","sam7","sam8","sam9"];
let result = shuffle(group);
assert.equal(result, group[0] != "sam1");
});
});
this is the error -
AssertionError: expected [ Array(9) ] to equal true
how do i compare the two to make it true? or is there a better way to show the array has been shuffled?
The first argument of assert.equal() is where your comparison should be,
so
assert.equal(result, group[0] != "sam1");
should be
assert.equal(comparison, 'message to display on failure');
and a better way to know if the array has been shuffled would be to compare every element in the result with the original array, so something like
for(int i = 0; i < group.length; i++) {
if (group[i] !== result[i]) {
return false;
}
}
although, depending on how you shuffle there is a chance it shuffles in to the same order.
see http://www.chaijs.com/api/assert/ for more details on assert
It looks like shuffle returns an array. So to check if your first element in result array is not the same as in group array you have to compare the first two elements of arrays. If you want to use assert method, you have to do it this way:
assert(result[0] != group[0], "string if the test fails");
Just at the top of this doc
The easy way is to compare the previous array and after array. Don't use equal here but instead deepEqual to compare array or object.
it('Shuffle should randomly move array items by their index', function(){
let group = ["sam1","sam2","sam3","sam4","sam5","sam6","sam7","sam8","sam9"];
let result = shuffle(group);
assert.deepEqual(result, group);
});
});
Ref: http://www.chaijs.com/api/assert/#method_deepequal
Something like this?
assert.notEqual(group[0], "sam1");
You can find the list of usable functions here
http://www.chaijs.com/api/assert/
expect(result).to.have.members(group); // to check if all members there - doesn't care about the order
expect(result).to.not.eql(group); // to check if order has changed - there's a catch though; only 1 change on order (e.g. `shuffle` swapped **just** 2 members) is sufficient to this assertion to pass
Sources;
https://medium.com/building-ibotta/testing-arrays-and-objects-with-chai-js-4b372310fe6d
https://www.chaijs.com/api/bdd/#method_members
https://www.chaijs.com/api/bdd/#method_eql
I'm new to JavaScript and feel like I must be missing something fundamental here!
I'm creating a function which sorts a list of integers list and returns the minimum value listSort[0].
function sortNumber(a,b) {
return a - b;
}
var min = function(list){
console.log(list[0]);
var listSort = list.sort(sortNumber);
console.log(list[0]);
console.log(listSort[0]);
return list[0];
}
Can anyone explain why the value of list[0] changes after list.sort(sortNumber) is assigned to listSort ?
Thanks!
The sort() function directly changes the array to which is applied. For example:
myArray.sort();
directly changes the content of myArray.
If you do not want to change the content of the original array you need to use a cloning function:
function mySortingFunction(list){
var newList = myCloningFunction(list);
newList.sort();
return newList;
}
There are several ways to clone an array:
Javascript fastest way to duplicate an Array - slice vs for loop
If you use AngularJS you can simply write:
var newList = angular.copy(list);
To get the minimum value of an Array, better use Math.min
var list = [4,2,4,2,6,5,2,4,3,5,2];
var min = Math.min.apply(null, list);
If i'm right, it's because when you use your assignment, you are executing list.sort(sortNumber) and so list change as per the assignment function.
Sooo... read like this :
- list.sort(sortNumber) => List change
- list is assigned to listSort
Despite this fact, I think you're going to far to find the min value. :P
I'm new to JS and am having trouble getting my head around the "forEach" method.
To help illustrate, let's say that I have 2 arrays.
The first: an array containing 1000 random words from the dictionary.
The second: an array containing 10 "stopwords" (words that I'd like to filter out of the first array).
If I sit down and write a function that takes these two arrays parameters, my intuition would tell me to code it like this:
function cleanSet(theSet, stoppers){
for(var i=0;i<theSet.length;i++){
for(var j=0; j<stoppers.length;j++){
if(theSet[i] === stoppers[j]){
theSet.splice(i,1);
}
}
}
return theSet;
}
However, when I try to use forEach while writing this program, it doesn't work:
function cleanerSet(theSet, stoppers){
theSet.forEach(function(setWord,i){
stoppers.forEach(function(stopper, j){
if(theSet[i] === stopper[j]){
theSet.splice(i,1);
}
});
});
return theSet;
}
Why isn't "cleanerSet" working the way "cleanSet" is?
The problem is that splice mutates your array, so you have to keep in mind that if you delete an item from the array that you are currently iterating, your index is not reset. As far as how to solve it, #Gyandeep provides a good solution. Also, in your first implementation, I think you might've meant:
theSet.splice(i,1);
I think this is what you want to do
function cleanerSet(theSet, stoppers){
return theSet.filter(function(setWord,i){
return stoppers.indexOf(setWord) === -1;
});
}
Runtime:
cleanerSet([1,2,3,4,5], [2,4]) // [1, 3, 5]
Within the callback you pass to the foreach function, the currently iterated value is stored in the first parameter of the function and the current index is stored in the second parameter. So when you check for equality you don't need to reference the index; simply use the parameter (i.e. setWord or stopper).
Additionally, when you call splice, the second parameter should be the number of items you'd like removed, so you need to pass 1, not 'i'.
This modified function should work:
function cleanerSet(theSet, stoppers){
theSet.forEach(function(setWord, i){
stoppers.forEach(function(stopper){
if(setWord === stopper){
theSet.splice(i,1);
}
});
});
return theSet;
}