How can I use a Function to determine if a Value exists in a Javascript Array? - javascript

I will be using an input field where a person types in a value.
I create the variable that they will type in: 'Ben'.
I want the function to loop thru the nameArray and return true or false.
The script is not working and I know it is rather simple.
function validateNames() {
var name = "Ben";
var nameArray = ["Bill", "Barry", "Zack", "Will"];
var arrayLength = nameArray.length;
for (var i = 0; i < arrayLength; i++) {
//Do something
if (name != nameArray[i]) {
alert((nameArray[i]) + "Name is not valid.");
console.log("Name is not found in array.");
} else {
return true;
console.log(nameArray[i]);
}
}
}

The only way for your loop logic to know that the value is not in the array is to go through the whole array first. Your loop will be alerting on every iteration until it finds a match. It also doesn't make sense to put a console.log after a return because the former will never execute:
function validateNames() {
var name = "Ben";
var nameArray = ["Bill", "Barry", "Zack", "Will"];
var arrayLength = nameArray.length;
for (var i = 0; i < arrayLength; i++) {
if (name === nameArray[i]) {
console.log(nameArray[i]);
return true;
}
}
console.log("Name is not found in array.");
return false;
}
validateNames();
Javascript arrays also provide a handy method for checking whether they contain a certain value. it's called .indexOf(), and it returns -1 when there's no match:
function validateNames() {
var name = "Ben";
var nameArray = ["Bill","Barry","Zack","Will"];
return nameArray.indexOf(name) !== -1;
}

You could use .indexOf():
var nameArray = ["Bill","Barry","Zack","Will"];
nameArray.indexOf("Bill"); // Returns 0, Bill is found
nameArray.indexOf("Hillary"); // Returns -1, Hillary not found
So your function could look like:
function validateName(name) {
return nameArray.indexOf(name) !== -1;
}
Please bear in mind it does not work on IE8 or below.

easy fix :)
var nameArray = ["Bill", "Barry", "Zack", "Will"];
console.log(validateName("Ben", nameArrray)); // False
console.log(validateName("Will", nameArrray)); // True
function validateName(name, arr){
var found = 0;
for(var i = 0; i < arr.length; i++){
found += (name === arr[i])? 1 : 0;
}
var result = (found>0)? true: false;
return result;
}

This will be false, because Ben does not exist in the array
if (nameArray.indexOf(name) > -1)
You can add a contains() method to the Array class so that you do not have to type this out each time.
// Static method
if (Array.contains === undefined) {
Array.contains = function(arr, val) {
return arr.indexOf(val) > -1;
}
}
// Instance method
if (Array.prototype.contains === undefined) {
Array.prototype.contains = function(val) {
return this.indexOf(val) > -1;
}
}
var nameArray = ["Bill", "Barry", "Zack", "Will"];
var name = "Ben";
Array.contains(nameArray, name); // false
nameArray.contains(name); // false
You could also use some Array.prototype.some.
if (Array.prototype.contains === undefined) {
Array.prototype.contains = function(val) {
return this.some(function(item) {
return item === name;
});
}
}
A better approach is to polyfill Array.prototype.includes(). This is an upcoming method in ECMAScript 7.
Polyfill
if (![].includes) {
Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {'use strict';
var O = Object(this);
var len = parseInt(O.length) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1]) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {k = 0;}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (searchElement === currentElement ||
(searchElement !== searchElement && currentElement !== currentElement)) {
return true;
}
k++;
}
return false;
};
}
Usage
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true

Related

Javascript Array includes returning false after JSON.parse

I am creating an array in javascript inserting an element into it and then checking for its existence using includes. It returns true.
But when I am converting the array into a string using JSON.stringify and then converting back to the array using JSON.parse and then testing for the same, it returns false.
This is baffling me.
var test_object = {'id': 1, 'name': 'Test'};
var initial = [];
initial.push(test_object);
console.log(initial.includes(test_object));
var later = JSON.stringify(initial);
later = JSON.parse(later);
console.log(later.includes(test_object));
Here is a jsbin for the same.
As winhowes states includes checks by identity not value.
you can try this:
if (!Array.prototype.includesCallback) {
Array.prototype.includesCallback = function(predicate) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.includeCallback called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return true;
}
}
return undefined;
};
}
which will let you utilize a function to perform the comparasin
later.includesCallback (
function(item) {
return item.id === test_object.id;
}
);
Array.prototype.includesEquivalent = function (obj) {
for (var o in this) {
for (var p in this[o]) {
if (this[o][p] !== obj[p]) {
return false;
}
}
}
return true;
}
var test_object = {'id': 1, 'name': 'Test'};
var initial = [];
initial.push(test_object);
console.log(initial.includes(test_object));
var later = JSON.stringify(initial);
later = JSON.parse(later);
console.log(later.includesEquivalent(test_object));
When you run json.parse you are returning a new object. Objects are compared by identity rather than value when using includes, which is why it returns false. If you wanted to you could modify the includes prototype (though I don't recommend doing this) to do a deeper object comparison
Array.prototype.includes = function(searchElement /*, fromIndex*/) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.includes called on null or undefined');
}
var O = Object(this);
var len = parseInt(O.length, 10) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1], 10) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {k = 0;}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (JSON.stringify(searchElement) === JSON.stringify(currentElement) || searchElement === currentElement ||
(searchElement !== searchElement && currentElement !== currentElement)) { // NaN !== NaN
return true;
}
k++;
}
return false;
};
Note that this code is based on the Array.prototype.includes polyfill.

Javascript :: prevent Uncaught Error when page is loaded

I have an intersection function being fed by an input <form>
var chatArr = [];
function input() {
var chat = document.getElementById("yousay").value;
chatArr.push(chat);
var words = chatArr.join(' ').match(/\S+/g);
if(chat.length == 0){
console.log("Mithras hears you")
}
else if(words.length > 1){
return words;
}
else{
console.log(chat)
};
}
then:
function setIntersection(a, b) {
var result = [];
for (var i = 0; i < a.length; i++) {
if (b.indexOf(a[i]) !== -1 && result.indexOf(a[i]) === -1) {
result.push(a[i]);
}
}
return result;
}
which, on its turn, passes into this function:
Song.prototype.lyricsIntersect = function(input) {
var bestSong = null;
var bestCount = -Infinity;
for (var i in songs) {
var currentCount = setIntersection(songs[i].lyrics, input()).length;
(...)
When the page is loaded, however, the form is obviously empty, so I get:
Uncaught TypeError: Cannot read property 'indexOf' of undefined
How do I prevent this error when page is loaded?
Try to declare your array like this:
var result = new Array(a.length);
Try adding some protection to the if sentence, like this:
function setIntersection(a, b) {
var result = [];
for (var i = 0; i < a.length; i++) {
if (
typeof b != "undefined" && /* added protection */
b.indexOf(a[i]) !== -1 && result.indexOf(a[i]) === -1) {
result.push(a[i]);
}
}
return result;
}
Now, as this code is inside a loop, the best you can do is avoid any iteration if b is undefined, so that:
function setIntersection(a, b) {
var result = [];
/* added protection */
if(typeof b != "undefined") return result;
for (var i = 0; i < a.length; i++) {
if (b.indexOf(a[i]) !== -1 && result.indexOf(a[i]) === -1) {
result.push(a[i]);
}
}
return result;
}
Basically, every value that the parameters of your function might be should be taken into account and add protection if necessary
Check for Array Length before getting index of Array,
if(result.length > 0)
{
if (b.indexOf(a[i]) !== -1 && result.indexOf(a[i]) === -1) {
result.push(a[i]);
}
}

Remove duplicate item from array Javascript [duplicate]

This question already has answers here:
Get all non-unique values (i.e.: duplicate/more than one occurrence) in an array
(97 answers)
Closed 8 years ago.
I'm looking for an easy way of removing a duplicate value from an array. I figured out how to detect if there is a duplicate or not, just I don't know how to "push" it from the value. For example, if you go to the link provided, and then type, "abca" (press return/enter key after each letter).. it will alert "duplicate!"
But I also want to figure out how to remove that duplicate from the textarea?
http://jsfiddle.net/P3gpp/
This is the part that seems to not be working ::
sort = sort.push(i);
textVal = sort;
return textVal;
Why do it the hard way, it can be done more easily using javascript filter function which is specifically for this kind of operations:
var arr = ["apple", "bannana", "orange", "apple", "orange"];
arr = arr.filter( function( item, index, inputArray ) {
return inputArray.indexOf(item) == index;
});
---------------------
Output: ["apple", "bannana", "orange"]
Based on user2668376 solution, this will return a new array without duplicates.
Array.prototype.removeDuplicates = function () {
return this.filter(function (item, index, self) {
return self.indexOf(item) == index;
});
};
After that you can do:
[1, 3, 3, 7].removeDuplicates();
Result will be; [1, 3, 7].
These are the functions I created/use for removing duplicates:
var removeDuplicatesInPlace = function (arr) {
var i, j, cur, found;
for (i = arr.length - 1; i >= 0; i--) {
cur = arr[i];
found = false;
for (j = i - 1; !found && j >= 0; j--) {
if (cur === arr[j]) {
if (i !== j) {
arr.splice(i, 1);
}
found = true;
}
}
}
return arr;
};
var removeDuplicatesGetCopy = function (arr) {
var ret, len, i, j, cur, found;
ret = [];
len = arr.length;
for (i = 0; i < len; i++) {
cur = arr[i];
found = false;
for (j = 0; !found && (j < len); j++) {
if (cur === arr[j]) {
if (i === j) {
ret.push(cur);
}
found = true;
}
}
}
return ret;
};
So using the first one, this is how your code could look:
function cleanUp() {
var text = document.getElementById("fld"),
textVal = text.value,
array;
textVal = textVal.replace(/\r/g, " ");
array = textVal.split(/\n/g);
text.value = removeDuplicatesInPlace(array).join("\n");
}
DEMO: http://jsfiddle.net/VrcN6/1/
You can use Array.reduce() to remove the duplicates. You need a helper object to keep track of how many times an item has been seen.
function cleanUp()
{
var textBox = document.getElementById("fld"),
array = textBox.value.split(/\r?\n/g),
o = {},
output;
output = array.reduce(function(prev, current) {
var key = '$' + current;
// have we seen this value before?
if (o[key] === void 0) {
prev.push(current);
o[key] = true;
}
return prev;
}, []);
// write back the result
textBox.value = output.join("\n");
}
The output of the reduce() step can be used directly to populate the text area again, without affecting the original sort order.
Demo
You can do this easily with just an object:
function removeDuplicates(text) {
var seen = {};
var result = '';
for (var i = 0; i < text.length; i++) {
var char = text.charAt(i);
if (char in seen) {
continue;
} else {
seen[char] = true;
result += char;
}
}
return result;
}
function cleanUp() {
var elem = document.getElementById("fld");
elem.value = removeDuplicates(elem.value);
}
arr3 = [1, 2, 3, 2, 4, 5];
unique = [];
function findUnique(val)
{
status = '0';
unique.forEach(function(itm){
if(itm==val){
status=1;
}
})
return status;
}
arr3.forEach(function(itm){
rtn = findUnique(itm);
if(rtn==0)
unique.push(itm);
});
console.log(unique); // [1, 2, 3, 4, 5]

Does jQuery have a method for checking all values of an array to see if they meet some criteria?

I'm looking for something similar to Groovy's every() method, which tests every element of a list if it meets some criteria. If they all meet the criteria, the function returns true. Otherwise, false. I've tried something like this:
var arr = [1, 0, 1, 0, 1, 1];
var allOnes = $.grep(arr, function(ind) {
return this == 1;
}).length == arr.length;
..but its not very clean. I haven't had any luck while searching through the API. Is using grep() the only way to do it?
if it is a plain js array, you have $.grep()
.filter() is for use with jQuery or DOM Elements
Here is a plugin I made that might make it easier:
(function($) {
$.fn.allOnes = function() {
var allVal = true;
this.each(function(ind, item) {
if (item != 1) {
allVal = false;
return allVal;
}
});
return allVal;
};
})(jQuery);
var arr = [1, 1, 0, 1, 1, 1];
console.log($(arr).allOnes());
Fiddle: http://jsfiddle.net/maniator/NctND/
The following plugin is an expansion of the above and lets you search for a specific number: http://jsfiddle.net/maniator/bFNnn/
(function($) {
$.fn.allValue = function(pred) {
var allOnes = true;
this.each(function(ind, item) {
if (item != pred) {
allOnes = false;
return allOnes;
}
});
return allOnes;
};
})(jQuery);
var arr = [1, 1, 1, 1, 1, 1];
console.log($(arr).allValue(1));
here is example of function you can use.
var arr = [1, 0, 1, 0, 1, 1];
var allOnes = arr.check(1);
//this function compares all elements in array and if all meet the criteria it returns true
Array.prototype.chack = function(cond)
{
var ln = 0;
for(i=0; i<this.length; i++)
{
if(bond === this[i])
{
ln++
}
}
if(ln == this.length)
return true;
else
return false;
}
How about just turning your working code into a method on array, to ease its reuse:
Array.prototype.every = function(predicate){
return $.grep(this,predicate).length == this.length;
}
usage:
alert([1,0,1,0].every(function(i) { return i == 1; }));
Working example: http://jsfiddle.net/59J5A/
Edit: changed to grep
You could always implement an allOnes method:
function allOnes(array) {
var result = [];
for(var i = 0; i < array.length; i += 1) {
if (array[i] === 1) { result.push(true); }
}
return array.length == result.length;
}
or you could be a bit more abstract and test for true/false:
function all(array) {
var result = [];
for(var i = 0; i < array.length; i += 1) {
if (array[i]) { result.push(true); }
}
return array.length == result.length;
}
var arr = [1, 0, 1, 0, 1, 1];
var allOnes = all(arr);
or even better, maybe have a changeable predicate:
function all(array, predicate) {
var result = [],
predicate = predicate || function(x) { if (x) { return true; } };
for(var i = 0; i < array.length; i += 1) {
if (predicate(array[i])) { result.push(true); }
}
return array.length == result.length;
}
var allOnes = all(arr, function(x) { return x === 1; })

replace items which appear in both arrays in javascript

I have two arrays and want to remove from one all elements which exist in the other as well.
Can this be done with native JS?
Is there a jQuery function to do it?
What are best practices to do so (the
faster the better)
p.s.: just post code in other languages too, maybe I can port it to Javascript
Update, after accepting answer to help the JS dudes ;-)
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
// Array Contains - By Helmuth Lammer (TU Vienna)
Array.prototype.contains = function(key){
for(var i = 0; i<this.length; i++){
if(this[i] == key) return i;
}
return false;
}
(There is a native JS method named contains too, but it should work)
Given two sets a and b, to remove all elements present in a from b. Translation to array formatting and javascript left as an exercise to the reader. Optimizations exist for sorted arrays.
for(element e : b) {
if(a.contains(e)) {
b.remove(e);
}
}
var foo = [1, 2, 3, 4, 5];
function removeAll(a, b) {
var i = 0,
j;
while (i < b.length) {
for (j = 0; j < a.length; j++) {
if (a[j] === b[i]) {
b.splice(i, 1);
i--;
break;
}
}
i++;
}
}
removeAll([2, 4], foo);
// foo === [1, 3, 5]
[See it in action]
// two arrays
var arr1 = [1,2,3,4,5];
var arr2 = [4,5,6,7,8];
// returns the element's index in an array
// or -1 if there isn't such an element
function indexOf( arr, el ) {
for ( var i = arr.length; i--; ) {
if ( arr[i] === el ) return i;
}
return -1;
}
// go through array1 and remove all
// elements which is also in array2
​for ( var i = arr1.length; i--; )​ {
if ( indexOf( arr2, arr1[i] ) !== -1 ) {
arr1.splice(i, 1);
}
}
// result should be: arr1 = [1,2,3]
alert( arr1 );
​
I had to write a code once where an Ajax call would return an array containing a list of element which must be deleted from a local (client-side) array.
I ended implementing it this way:
// The filter method creates a new array with all elements that pass the
// test implemented by the provided function.
local_array = local_array.filter( function (element) {
// Now I check if this element is present in the "delete" array. In order to do
// that I use the "some" method which runs a callback function for each of the
// array elements and returns true or false.
return !items_to_delete.some( function(item) {
return item.pk === element.pk;
});
});
Edit:
In order to make it cross-browser (I am talking about IE here). You will have to define the some and filter functions. Just put this somewhere in your code:
if (!Array.prototype.some)
{
Array.prototype.some = function(fun /*, thisp*/)
{
var i = 0,
len = this.length >>> 0;
if (typeof fun != "function")
throw new TypeError();
var thisp = arguments[1];
for (; i < len; i++)
{
if (i in this &&
fun.call(thisp, this[i], i, this))
return true;
}
return false;
};
}
if (!Array.prototype.filter)
{
Array.prototype.filter = function(fun /*, thisp*/)
{
var len = this.length >>> 0;
if (typeof fun != "function")
throw new TypeError();
var res = [];
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in this)
{
var val = this[i]; // in case fun mutates this
if (fun.call(thisp, val, i, this))
res.push(val);
}
}
return res;
};
}

Categories