I'm only able to return 1 array - javascript

I'm trying to take this array and split it into 2 new arrays, evens and odds and return them. When I run the code below I am only getting the odds, why is that? And what can I do to solve it?
Thanks in advance.
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return(evens, odds);
}
divider(numbersArray);

Because JavaScript can only return one value. Ever.
return(evens, odds)
evaluates to the same value as
return odds
due to the comma operator wrapped in grouping parenthesis.
Perhaps returning an array of arrays (or even an object of arrays) is useful..
return [evens, odds]

You should return your results as an array.
return [evens, odds];
And then to access the results:
var evens;
var odds;
var arrayResults = divider(numbersArray);
evens = arrayResults[0];
odds = arrayResults[1];
console.log(evens);
console.log(odds);

In Javascript, you can only return ONE value. So, if you want to return multiples values, to separate them, you can put them in an array or in an object :
return([evens, odds]);
OR
return({evens: evens, odds: odds})

The result of evaluating (evens, odds) is odds, that is returned thus.
This is how comma operator works.
Use the following statement instead:
return { 'evens': evens, 'odds': odds };
As an example:
var v = divider(numberArrays);
v.evens; // get evens this way
v.odds; // get odds this way

You can return only one entity from a function. Its better to wrap your results in single object.
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens:evens, odds:odds};
}
divider(numbersArray);

Es5 doesn't support tuples, You should wrap your return
in an object like here
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens:evens,
odds:odds};
}
divider(numbersArray);
Or in an array as the other aswers show

You could return an object, like this:
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens, odds};
}
divider(numbersArray);

Related

JSON.stringify not working when comparing two arrays

I am trying to compare two arrays and check if they are the same. According to the logic below the function should return DRAW as the arrays I am comparing to are exactly the same. It returns undefined instead. I cannot figure it out why it doesn't return draw. If I change the && to || it returns draw so I assume there is an issue with the logical operator.
function isSolved(board) {
// TODO: Check if the board is solved!
var arraya = [1,1,1];
var arrayb = [2,2,2];
for (var i = 0; i < board.length; i++){
for (var j = 0; j < board[i].length; j++) {
if (board[i][j] === 0) {
return false;
} else if (
(JSON.stringify(board[i]) === JSON.stringify(arraya))
&& (JSON.stringify(board[i]) ===JSON.stringify(arrayb))) {
return "draw"
}
}
}
}
console.log(
isSolved([
[1,1,1],
[1,2,2],
[2,2,2]
])
);
You can use JSON.stringify like this:
var arraya = [1,1,1];
var arrayb = [2,2,2];
function isSolved(a, b) {
return JSON.stringify(a) === JSON.stringify(b) ? "draw" : false;
};
var input = [[1,1,1], [1,2,2], [2,2,2]];
for (var item of input) {
console.log(isSolved(item, arraya));
console.log(isSolved(item, arrayb));
console.log("=====");
}

Check if an array contains duplicate values [duplicate]

This question already has answers here:
In Javascript, how do I check if an array has duplicate values?
(9 answers)
Closed 10 months ago.
I wanted to write a javascript function which checks if array contains duplicate values or not.
I have written the following code but its giving answer as "true" always.
Can anybody please tell me what am I missing.
function checkIfArrayIsUnique(myArray)
{
for (var i = 0; i < myArray.length; i++)
{
for (var j = 0; j < myArray.length; j++)
{
if (i != j)
{
if (myArray[i] == myArray[j])
{
return true; // means there are duplicate values
}
}
}
}
return false; // means there are no duplicate values.
}
An easy solution, if you've got ES6, uses Set:
function checkIfArrayIsUnique(myArray) {
return myArray.length === new Set(myArray).size;
}
let uniqueArray = [1, 2, 3, 4, 5];
console.log(`${uniqueArray} is unique : ${checkIfArrayIsUnique(uniqueArray)}`);
let nonUniqueArray = [1, 1, 2, 3, 4, 5];
console.log(`${nonUniqueArray} is unique : ${checkIfArrayIsUnique(nonUniqueArray)}`);
let arr = [11,22,11,22];
let hasDuplicate = arr.some((val, i) => arr.indexOf(val) !== i);
// hasDuplicate = true
True -> array has duplicates
False -> uniqe array
This should work with only one loop:
function checkIfArrayIsUnique(arr) {
var map = {}, i, size;
for (i = 0, size = arr.length; i < size; i++){
if (map[arr[i]]){
return false;
}
map[arr[i]] = true;
}
return true;
}
You got the return values the wrong way round:
As soon as you find two values that are equal, you can conclude that the array is not unique and return false.
At the very end, after you've checked all the pairs, you can return true.
If you do this a lot, and the arrays are large, you might want to investigate the possibility of sorting the array and then only comparing adjacent elements. This will have better asymptotic complexity than your current method.
Assuming you're targeting browsers that aren't IE8,
this would work as well:
function checkIfArrayIsUnique(myArray)
{
for (var i = 0; i < myArray.length; i++)
{
if (myArray.indexOf(myArray[i]) !== myArray.lastIndexOf(myArray[i])) {
return false;
}
}
return true; // this means not unique
}
Here's an O(n) solution:
function hasDupes(arr) {
/* temporary object */
var uniqOb = {};
/* create object attribute with name=value in array, this will not keep dupes*/
for (var i in arr)
uniqOb[arr[i]] = "";
/* if object's attributes match array, then no dupes! */
if (arr.length == Object.keys(uniqOb).length)
alert('NO dupes');
else
alert('HAS dupes');
}
var arr = ["1/1/2016", "1/1/2016", "2/1/2016"];
hasDupes(arr);
https://jsfiddle.net/7kkgy1j3/
Another solution:
Array.prototype.checkIfArrayIsUnique = function() {
this.sort();
for ( var i = 1; i < this.length; i++ ){
if(this[i-1] == this[i])
return false;
}
return true;
}
function hasNoDuplicates(arr) {
return arr.every(num => arr.indexOf(num) === arr.lastIndexOf(num));
}
hasNoDuplicates accepts an array and returns true if there are no duplicate values. If there are any duplicates, the function returns false.
Without a for loop, only using Map().
You can also return the duplicates.
(function(a){
let map = new Map();
a.forEach(e => {
if(map.has(e)) {
let count = map.get(e);
console.log(count)
map.set(e, count + 1);
} else {
map.set(e, 1);
}
});
let hasDup = false;
let dups = [];
map.forEach((value, key) => {
if(value > 1) {
hasDup = true;
dups.push(key);
}
});
console.log(dups);
return hasDup;
})([2,4,6,2,1,4]);
Late answer but can be helpful
function areThereDuplicates(args) {
let count = {};
for(let i = 0; i < args.length; i++){
count[args[i]] = 1 + (count[args[i]] || 0);
}
let found = Object.keys(count).filter(function(key) {
return count[key] > 1;
});
return found.length ? true : false;
}
areThereDuplicates([1,2,5]);
The code given in the question can be better written as follows
function checkIfArrayIsUnique(myArray)
{
for (var i = 0; i < myArray.length; i++)
{
for (var j = i+1; j < myArray.length; j++)
{
if (myArray[i] == myArray[j])
{
return true; // means there are duplicate values
}
}
}
return false; // means there are no duplicate values.
}
Returns the duplicate item in array and creates a new array with no duplicates:
var a = ["hello", "hi", "hi", "juice", "juice", "test"];
var b = ["ding", "dong", "hi", "juice", "juice", "test"];
var c = a.concat(b);
var dupClearArr = [];
function dupArray(arr) {
for (i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) != i && arr.indexOf(arr[i]) != -1) {
console.log('duplicate item ' + arr[i]);
} else {
dupClearArr.push(arr[i])
}
}
console.log('actual array \n' + arr + ' \nno duplicate items array \n' + dupClearArr)
}
dupArray(c);
const containsMatches = (a1, a2) => a1.some((v) => a2.includes(v));
If your array nests other arrays/objects, using the Set approach may not be what you want since comparing two objects compares their references. If you want to check that their contained values are equal, something else is needed. Here are a couple different approaches.
Approach 1: Map using JSON.stringify for keys
If you want to consider objects with the same contained values as equal, here's one simple way to do it using a Map object. It uses JSON.stringify to make a unique id for each element in the array.
I believe the runtime of this would be O(n * m) on arrays, assuming JSON.stringify serializes in linear time. n is the length of the outer array, m is size of the arrays. If the objects get very large, however, this may slow down since the keys will be very long. Not a very space-efficient implementation, but it is simple and works for many data types.
function checkArrayDupeFree(myArray, idFunc) {
const dupeMap = new Map();
for (const el of myArray) {
const id = idFunc(el);
if (dupeMap.has(id))
return false;
dupeMap.set(id, el);
}
return true;
}
const notUnique = [ [1, 2], [1, 3], [1, 2] ];
console.log(`${JSON.stringify(notUnique)} has no duplicates? ${checkArrayDupeFree(notUnique, JSON.stringify)}`);
const unique = [ [2, 1], [1, 3], [1, 2] ];
console.log(`${JSON.stringify(unique)} has no duplicates? ${checkArrayDupeFree(unique, JSON.stringify)}`);
Of course, you could also write your own id-generator function, though I'm not sure you can do much better than JSON.stringify.
Approach 2: Custom HashMap, Hashcode, and Equality implementations
If you have a lot of big arrays, it may be better performance-wise to implement your own hash/equality functions and use a Map as a HashMap.
In the following implementation, we hash the array. If there is a collision, map a key to an array of collided values, and check to see if any of the array values match according to the equality function.
The downside of this approach is that you may have to consider a wide range of types for which to make hashcode/equality functions, depending on what's in the array.
function checkArrayDupeFreeWHashes(myArray, hashFunc, eqFunc) {
const hashMap = new Map();
for (const el of myArray) {
const hash = hashFunc(el);
const hit = hashMap.get(hash);
if (hit == null)
hashMap.set(hash, [el]);
else if (hit.some(v => eqFunc(v, el)))
return false;
else
hit.push(el);
}
return true;
}
Here's a demo of the custom HashMap in action. I implemented a hashing function and an equality function for arrays of arrays.
function checkArrayDupeFreeWHashes(myArray, hashFunc, eqFunc) {
const hashMap = new Map();
for (const el of myArray) {
const hash = hashFunc(el);
const hit = hashMap.get(hash);
if (hit == null)
hashMap.set(hash, [el]);
else if (hit.some(v => eqFunc(v, el)))
return false;
else
hit.push(el);
}
return true;
}
function arrayHasher(arr) {
let hash = 19;
for (let i = 0; i < arr.length; i++) {
const el = arr[i];
const toHash = Array.isArray(el)
? arrayHasher(el)
: el * 23;
hash = hash * 31 + toHash;
}
return hash;
}
function arrayEq(a, b) {
if (a.length != b.length)
return false;
for (let i = 0; i < a.length; i++) {
if ((Array.isArray(a) || Array.isArray(b)) && !arrayEq(a[i], b[i]))
return false;
else if (a[i] !== b[i])
return false;
}
return true;
}
const notUnique = [ [1, 2], [1, 3], [1, 2] ];
const unique = [ [2, 1], [1, 3], [1, 2] ];
console.log(`${JSON.stringify(notUnique)} has no duplicates? ${checkArrayDupeFreeWHashes(notUnique, arrayHasher, arrayEq)}`);
console.log(`${JSON.stringify(unique)} has no duplicates? ${checkArrayDupeFreeWHashes(unique, arrayHasher, arrayEq)}`);
function checkIfArrayIsUnique(myArray)
{
isUnique=true
for (var i = 0; i < myArray.length; i++)
{
for (var j = 0; j < myArray.length; j++)
{
if (i != j)
{
if (myArray[i] == myArray[j])
{
isUnique=false
}
}
}
}
return isUnique;
}
This assume that the array is unique at the start.
If find two equals values, then change to false
i think this is the simple way
$(document).ready(function() {
var arr = [1,2,3,9,6,5,6];
console.log( "result =>"+ if_duplicate_value (arr));
});
function if_duplicate_value (arr){
for(i=0;i<arr.length-1;i++){
for(j=i+1;j<arr.length;j++){
if(arr[i]==arr[j]){
return true;
}
}
}
return false;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
var c=[2,2,3,3,5,5,4,4,8,8];
for(var i=0; i<b.length; i++){
for(var j=i+1; j<b.length; j++){
if(c[i]==c[j]){
console.log(c[j]);
}
}
}

Array length undefined after split

I'd like to split a string ("1,2,3") and return it as an int array so I wrote the following function:
function stringToIntArray(string) {
var split = {};
split = string.split(',');
var selected = {};
for (var i = 0; i <= split.length; i++) {
selected[i] = split[i];
}
return selected;
}
However split.length is always undefinied. Where's my mistake?
var selected = {};
doesn't build an array but an object, which has no length property.
You can fix your code by replacing it with
var selected = [];
If you want to return an array of numbers, you can change your code to
function stringToIntArray(string) {
var split = string.split(',');
var selected = [];
for (var i = 0; i < split.length; i++) {
selected.push(parseInt(split[i], 10));
}
return selected;
}
Note that I replaced <= with < in your loop.
Note also that for modern browsers, you can use the map function to make it simpler :
function stringToIntArray(string) {
return string.split(',').map(function(v){ return parseInt(v, 10) });
}

how to remove the repeated value in an array and in between arrays using jQuery

In my code I need to find the repeated value and give an alert using jQuery. Below is the example arrays and my requirement. Please help.
a1 = {1,2,3,4,5,6,4}
a2= {9,8,7},
a3= {a,b,c,d,e,7}
In the above arrays I need to get the value 4 and give alert because it is repeating in array "a1" and I need to get the value 7 because it is repeating in the arrays 'a2' and 'a3'.
The first issue I fixed like as follows. Ineed to to fix the second one.
for (var $i = 0; $i<= $last; $i++)
{
var hours = [];
var minutes = [];
var activeTime = [];
$.each($('.hour'+$i),function() {
hours.push($(this).val());
});
$.each($('.hour'+$i).next('select'),function(){
minutes.push($(this).val());
});
for ( var i = 0; i < hours.length; i++ ) {
activeTime.push(hours[ i ]+":"+minutes[ i ]+":"+"00");
}
for ( var i = 0; i <= hours.length; i++ ) {
if ( hours[ i ] === "" )
{
$("#timeValidate"+$i).css("display", "block");
return false;
}
else
{
$("#timeValidate"+$i).css("display", "none");
}
}
for(var i=0; i< activeTime.length; i++)
{
for(var j = 0; j< activeTime.length; j++)
{
if( i != j)
{
if(activeTime[j] == activeTime[i])
{
$("#timeValidate"+$i).text("");
$("#timeValidate"+$i).text("active time"+activeTime[j]+" is repeating");
$("#timeValidate"+$i).css("display", "block");
return false;
}
}
}
}
}
function getDuplicatesFromArrays() {
var allItems = Array.prototype.concat.apply([], arguments);
var duplicates = [];
var hash = {};
allItems.forEach(function(x) {
if(hash.hasOwnProperty(x)) duplicates.push(x);
hash[x] = 1;
});
return duplicates;
}
The above function accepts any number of arrays, and yields the duplicates:
getDuplicatesFromArrays(a1,a2,a3) // [4, 7]
Demo
It works as sort of an inverse hash sieve; adding to duplicates only if the item was already in the hash.
Try sugar.js, it has advanced functions for arrays (and others). For example, you can use a combination of unique() and subtract() to get an array that contains only the elements that are repeated. Then you can parse it and alert for each one.
Here you go:
var original = [].concat(a,b,c),
dupes = [];
for (var c = 0; c < original.length; c++) {
if (original.filter(function(v) {
return v == original[c];
}).length > 1) {
dupes.push(original[c]);
}
}
alert($.grep(dupes, function(v, k){return $.inArray(v , dupes) === k;}));
Here is a demo: http://jsfiddle.net/q2c42/

Create an array and check against it

I am not sure of how to do this, but what I want to do it create an array and be able to add new items to this array. Since the items are supposed to be a random number, when a new instance is created I would like it to be checked against the rest of the array and be sure that the number it has generated is not already in the array. How would I accomplish something like this?
I looked at Šime Vidas's answer and it seems to work, but I tried to shorten it to
var arr = [];
function add(a) {
var n = ~~(Math.random() * 100);
for (var i = 0; i < a.length; i++) {
if ( a[i] === n) { a.push(n) }
}
}
for (var i=0; i<5; i++){
add(arr)
}
document.getElementById('output').innerHTML += arr;
and I don't understand why this wouldn't work. It does pretty much the same thing, correct?
var arr = [];
function add(a) {
var n = ~~(Math.random() * 1000);
!is(a, n) && a.push(n);
}
function is(a, n) {
for (var i = 0; i < a.length; i++) {
if ( a[i] === n ) { return true; }
}
return false;
}
The add function creates a random integer number between 0 and 1000, and adds it to the array.
The is function checks whether the n number is somewhere inside the a array.
Demo: http://jsfiddle.net/kHhMp/2/
Demo 2: http://jsfiddle.net/kHhMp/3/
(Demo 2 shows that a number will only be added to the array if it's not already in it.)
btw
!is(a, n) && a.push(n);
is a short form of this:
if ( is(a, n) == false ) { a.push(n); }
The number is added to the array only if is(a, n) returns false.
UPDATE
var arr = [];
function add(a) {
var n = ~~(Math.random() * 1000),
ok = true;
for (var i = 0; i < a.length; i++) {
if ( a[i] === n ) { ok = false; }
}
ok && a.push(n);
}
If you enjoy fast code and you have many items in your array, you should use an Object rather than an Array.
Instead of doing var my_array=[]; my_array.push(my_number), use var my_object = {}; my_object[my_number] = true to add items in your structure.
With that approach, you can easily check if a new number is already in there with an if (my_object[my_number]) { /* already there */ } else { /* not there yet */ }
Once you're done, you can extract the list of numbers as an array by either using var keys = Object.keys(my_object), or if that's not available, var keys=[],i=0;for (keys[i++] in my_object);, more or less.
You may extend the built in Array object for your needs.
Array.prototype.pushUnique = function(value) {
var len = this.length;
for(var i = 0; i < len; i++) {
if(this[i]===value) return;
}
this.push(value);
}
var uniques = new Array();
uniques.pushUnique(1);
uniques.pushUnique(2);
uniques.pushUnique(1);
// array will contain only 1 and 2
The fastest, most cross-browser way is to iterate over the array using a loop:
var arr = [];
function addNum(num) {
for (i = 0, len = arr.length; i < len; i++) {
if ( arr[i] === num ) { return false; }
}
arr.push(num);
}
Be sure to get the length of the array before you run the loop so the length property isn't constantly checked.
var array = []
array[0] = 'Item'
array[0] === undefined
# returns false
array[1] === undefined
# returns true

Categories