JavaScript function with loops not running fast enough - javascript

I'm trying to practice for an interview and found a challenge online to write a function that will take an array of numbers and only return values that exist just once in the array, and return those values in order. For example, the array [1, 3, 5, 6, 1, 4, 3, 6] should return [4, 5].
I have a script that is passing the tests but for some of the tests is running too slow. Am I going about this wrong? Is there some fundamental way to speed this up? The script starts with findTheNumbers, and a is the array input:
function findTheNumbers(a) {
var retVal = [];
var nonUnique = [];
for (var i = 0; i < a.length; i++){
var isUnique = true;
if (i != 0){
for (var j = 0; j < nonUnique.length; j++){
if (a[i] == nonUnique[j]){
isUnique = false;
break;
}
}
}
if (isUnique){
for (var k = 0; k < a.length; k++){
if (a[i] == a[k] && i != k){
isUnique = false;
nonUnique.push(a[i]);
break;
}
}
}
if (isUnique){
retVal.push(a[i]);
if (retVal.length == 2){
break;
}
}
}
retVal = sortArrayOfLengthOfTwo(retVal);
return retVal;
}
function sortArrayOfLengthOfTwo(array){
var retVal = [];
if (array[0] > array[1]){
retVal.push(array[1]);
retVal.push(array[0]);
} else {
retVal = array;
}
return retVal;
}
UPDATE -
Not sure where the best place for this is, but here is my new version based on the accepted answer's hints (which worked SO much faster):
function findTheNumbers(a) {
var retVal = [];
var dict = {};
for (var i = 0; i < a.length; i++){
dict[a[i]] = 1 + (dict[a[i]] || 0);
}
for (var key in dict){
if (dict[key] == 1){
retVal.push(parseInt(key));
}
}
return retVal;
}

When a program is too slow, the rule of thumb is to
first blame your algorithm
next blame your implementation (edit: as suggested by Bergi)
finally blame the language
In your case, you parse the whole array n times, that is, the complexity is o(n^2). You can do the same with only one full parse, and a dictionary of the count for each element.
Edit about your new algorithm
Your new algorithm is very good. For the sake of your interview I have some comments:
instead of var, you should consider using const as much as possible, and let otherwise
do not hesitate to put intermediate results within variables
use more descriptive names for your variables
Here's the way I would implement it:
function findTheUniqueNumbers(a) {
const numberCounts = {} // I prefer "new Map()" on recent env.
a.forEach( function(e) {
const previousCount = numberCounts[e] || 0
numberCounts[e] = previousCount + 1
} )
return Object.keys(numberCounts)
.filter( function(e) {
return numberCounts[e] === 1
} )
}
const uniqueNumber = findTheUniqueNumbers([1, 3, 5, 6, 1, 4, 3, 6])
console.log(uniqueNumber)

Related

JS detectNetwork Coding Exercise

I'm having trouble trying to solve the following JavaScript coding exercise.
Write the function detectNetwork. It should accept a string or a
number for its cardNumber argument, and should return the appropriate
network string (or undefined if there's no match), based on the
provided cardData.
What I'm struggling to figure out is how to write this function without hardcoding every behavior of the cardData array. I want to effectively use the cardData array as an argument of the function, but have no idea how to.
var cardData = [{
network: 'Visa', // card issuer (network)
prefixes: ['4'], // beginning digits
lengths: [13, 16, 19] // lengths of card numbers
},{
network: 'Mastercard',
prefixes: ['51', '52', '53', '54', '55'],
lengths: [16]
},{
network: 'American Express',
prefixes: ['34', '37'],
lengths: [15]
},{
network: 'Diner\'s Club',
prefixes: ['38', '39'],
lengths: [14]
}];
function detectNetwork(cardNumber, cardData) {
// your solution here
}
// example
var network = detectNetwork('343456789012345', cardData);
console.log(network); // --> 'American Express'
Here is my solution that works it this particular case)
function detectNetwork(cardNumber, cardData) {
// your solution here
if(typeof cardNumber === "number"){
cardNumber = cardNumber.toString()
}
for(let i = 0; i < cardData.length; i++){
if(cardData[i]['lengths'].includes(cardNumber.length) && cardData[i]['prefixes'].toString() === cardNumber[0]){
return cardData[i]['issuer/network'];
} else if (Number(cardData[i]['lengths'].toString()) === cardNumber.length){
return cardData[i]['issuer/network'];
};
};
return undefined
}
Main idea is first checking the length of card. If we found the element in the array with similar length, we are checking elements in array with prefixes inside this object. If we found similar prefix, returning the name of the network.
function detectNetwork(cardNumber, cardData) {
var answer = '';
var cardLength = cardNumber.length;
var firstTwoDigits = cardNumber[0] + cardNumber[1];
for (var i =0; i < cardData.length; i++){
var cardObj = cardData[i];
if (cardObj['lengths'] == cardLength){
var arrOfPrefixes = cardObj['prefixes'];
for (var j =0; j < arrOfPrefixes.length; j++){
if (arrOfPrefixes[j] === firstTwoDigits){
answer = cardObj['network'];
}
}
}
}
return answer;
}
My approach is
compare the cardNumber length with each issuer's lengths
if there's a match, find the target prefix length and slice the card number to match it
comparing each issuer's prefixes with card number's prefixes using for loop
if there's a match, update the issuer
function detectNetwork(cardNumber, cardData) {
if(typeof cardNumber === 'number'){
cardNumber = cardNumber.toString();
}
let cardLength = cardNumber.length;
let issuer;
for(let x = 0; x < cardData.length; x ++ ){
let currentIssueObj = cardData[x];
let currentIssueLengths = cardData[x].lengths;
let currentIssuePrefixes = currentIssueObj.prefixes;
if ( currentIssueLengths.includes(cardLength)) {
let targetPrefixesLength = findMaxPrefixesLength(currentIssuePrefixes);
let cardPrefixes = cardNumber.slice(0,targetPrefixesLength);
for( let index = 0; index < currentIssuePrefixes.length; index ++ ){
if( cardPrefixes === currentIssuePrefixes[index]) {
issuer = currentIssueObj['issuer/network'];
break;
}
}
}
}
return issuer;
}
//helper function
function findMaxPrefixesLength(arr){
let maxLength = arr[0].length;
for(let x = 1; x < arr.length; x ++ ){
if (arr[x].length > maxLength){
maxLength = arr[x].length;
}
}
return maxLength;
}
function detectNetwork(cardNumber, cardData) {
var output = "";
var input = String(cardNumber);
var firstDig = input.slice(0, 1);
var first2Dig = input.slice(0, 2);
for(var i = 0; i < cardData.length; i++){
if(cardData[i].prefixes.includes(firstDig) || cardData[i].prefixes.includes(first2Dig)){
output += cardData[i]['issuer/network'];
return output;
}
}
return undefined;
}
I know this question was posed a long time ago, but I saw it on the hack reactor website. If the answer helps anyone then I'm glad.
// This function loops over cardData and uses helper functions below to validate if the lengths and prefixes are found in cardNumber.
function detectNetwork(cardNumber, cardData) {
for (i = 0; i < cardData.length; i++) {
let card = cardData[i]
let cardLengthFound = findLengths(card.lengths)
let cardPrefixFound = findPrefixes(card.prefixes)
if(cardLengthFound && cardPrefixFound) {
return card['issuer/network']
}
}
}
// This function checks to see if the prefixes in cardNumber is same as the ones in cardData
function findPrefixes(arr) {
for (j = 0; j < arr.length; j++) {
if (cardNumber.toString().slice(0, 2).includes(arr[j])) {
return true;
}
}
}
// This function checks to see if the length in cardNumber is same as the ones in cardData
function findLengths(arr) {
for (k = 0; k < cardNumber.toString().length; k++) {
if (cardNumber.toString().length === arr[k]) {
return true;
}
}
}
I really liked Max's answer but I don't have enough rep to leave a comment under his post. I pretty much refactored his code because it was easy to understand. Here's my solution:
function detectNetwork(cardNumber, cardData) {
// your solution here
var inputCardLength = cardNumber.length;
var inputCardNumbers = cardNumber[0] + cardNumber[1];
for(let counter = 0; counter < cardData.length; counter++){
let length = cardData[counter]['lengths'];
let prefix = cardData[counter]['prefixes'];
let network = cardData[counter]['issuer/network'];
if((length.includes(inputCardLength)) && (prefix.toString() === inputCardNumbers)) {
return network;
} else if(Number(length) === inputCardLength) {
return network;
};
};
return undefined
};
One way to do this is to iterate over the cardData array, and then test the values of the prefixes and length keys against the cardNumber, ensuring we cast to either a string or an int, as the question states that cardNumber can be either a string or an int.
function detectNetwork(cardNumber, cardData) {
for(let i = 0, {length} = cardData; i < length; i++){
if(cardData[i].lengths.some(length => length === cardNumber.length) && cardData[i].prefixes.some(prefix => cardNumber.toString().startsWith(prefix.toString()))){
return cardData[i].network
}
}
}
The key parts are the Array.prototype.some() and String.prototype.startsWith() methods
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
Hope this helps - good luck with JS - check out https://www.youtube.com/channel/UCvjgXvBlbQiydffZU7m1_aw for a good intro for a new JS programmer :)

Output for javascript program is 'undefined' when trying to run in command line

I am working through some Javascript coding problems and I want to print the output of the array on my command line using node file.js but I keep getting undefined as the output. Not sure what I am doing wrong. I've tried adding a console.log statement in different areas of the code. Here is the code:
var sortArrayByParity = function(A) {
E = [];
O = [];
for (i = 0; i < A; i++){
if (A[i] % 2 === 0){
E.push(A[i]);
}
else {
O.push(A[i]);
}
}
return E.concat(O);
console.log(E);
};
You have a few issues with your code:
The console.log() after your return will not run, as any code after a return will not be executed as the function is no longer running.
Another issue is your for loop. Currently, you are not looping as your condition i < A isn't correct. Instead, you want to loop over the length of A using:
for(var i = 0; i < A.length; i++) {
// Do code
}
See example below:
var sortArrayByParity = function(A) {
E = [];
O = [];
for (var i = 0; i < A.length; i++) {
if (A[i] % 2 === 0) {
E.push(A[i]);
} else {
O.push(A[i]);
}
}
return E.concat(O);
};
var res = sortArrayByParity([1, 2, 3, 4]);
console.log(res); // [2, 4, 1, 3] (sorted by evens first, odds second)
well there is some validation you should do.
Make sure to pass an array
You missing to add the A.length in the for loop
var sortArrayByParity = function(A) {
let E = [];
let O = [];
let errMsg = ''
// Make sure you're passing and array
if ( ! A instanceof Array ) {
return errMsg = ' Argument is not an array '
}
for (let i = 0; i < A.length; i++){
if (A[i] % 2 === 0){
E.push(A[i]);
}
else {
O.push(A[i]);
}
}
console.log(E);
return E.concat(O);
};
this should work ;)

Finding first duplicate in an array and returning the minimal index

So the question reads:
Given an array a that contains only numbers in the range from 1 to a.length, find the first duplicate number for which the second occurrence has the minimal index. In other words, if there are more than 1 duplicated numbers, return the number for which the second occurrence has a smaller index than the second occurrence of the other number does. If there are no such elements, return -1.
Write a solution with O(n) time complexity and O(1) additional space complexity.
I have a solution, but apparently it's not fast enough and stalls when there are over a thousand items in the array.
This is what I have:
function firstDuplicate(arr) {
let dictionary = {};
for(let i = 0, ii = arr.length; i < ii; i++) {
for(let z = i+1, zz = arr.length; z < zz; z++) {
if(arr[i] === arr[z]) {
if(dictionary.hasOwnProperty(arr[i])) {
if(dictionary[arr[i]] !== 0 && dictionary[arr[i]] > z) {
dictionary[i] = z;
}
} else {
dictionary[arr[i]] = z;
}
}
}
}
let answer = [];
for(key in dictionary) {
// [array number, position];
answer.push([key, dictionary[key]]);
};
if(answer.length > 0) {
return Number(answer.sort((a, b) => {
return a[1]-b[1];
})[0][0]);
}
return -1;
}
I think converting the object into an array and then sorting the array after the answers are complete slows down the whole function. Using built in JS methods like forEach, map and sort (like I did above), slows the code/function down even more. There is obviously a better and more accurate way to do this, so I'm asking for some JS masterminds to help me out on this.
you can keep adding numbers to a dictionary as keys with values as their index, and as soon as you find a repeating key in the dictionary return its value. This will be O(n) time complexity and O(n) space complexity.
function firstDuplicate(arr) {
var dictionary = {};
for(var i = 0; i < arr.length; i++) {
if(dictionary[arr[i]] !== undefined)
return arr[i];
else
dictionary[arr[i]] = i;
}
return -1;
}
console.log(firstDuplicate([2, 3, 3, 1, 5, 2]));
Since the numbers are between 1 to arr.length you can iterate on the array. For each arr[i] use arr[i] as index and make the element present and arr[arr[i]] negative, then the first arr[arr[i]] negative return arr[i]. This give O(1) space complexity and O(n) time complexity you can do this:
function firstDuplicate(arr) {
for(var i = 0; i < arr.length; i++) {
if(arr[Math.abs(arr[i])] < 0)
return Math.abs(arr[i]);
else
arr[Math.abs(arr[i])] = 0 - arr[Math.abs(arr[i])];
}
return -1;
}
console.log(firstDuplicate([2, 3, 3, 1, 5, 2]));
function firstDuplicate(arr) {
for(var i = 0; i < arr.length; i++) {
var num = Math.abs(arr[i]);
if(arr[num] < 0)
return num;
arr[num] = - arr[num];
}
return -1;
}
console.log(firstDuplicate([2,2,3,1,2]));
function firstDuplicate(arr) {
var numMap = {};
for (var i = 0; i < arr.length; i++) {
if (numMap[arr[i]]) {
return arr[i];
}
numMap[arr[i]] = true;
}
return -1;
}
Answer mentioned by #dij is great, but will fail for [2,2] or [2,3,3],
a little change
for input [2,2], i=0 we get a[ Math.abs[a[0] ] = a[2] = undefined
so we remove 1 from a[ Math.abs[a[0] -1 ] this will work now
function firstDuplicate(arr) {
for(var i = 0; i < arr.length; i++) {
if(arr[Math.abs(arr[i])-1] < 0)
return Math.abs(arr[i]);
else
arr[Math.abs(arr[i])-1] = 0 - arr[Math.abs(arr[i])-1];
}
return -1;
}
Please try the code below:
function getCountOccurence(A) {
let result = [];
A.forEach(elem => {
if (result.length > 0) {
let isOccure = false;
result.some((element) => {
if (element.element == elem) {
element.count++;
isOccure = true;
}
});
if (!isOccure) {
result.push({element: elem, count: 1});
}
} else {
result.push({element: elem, count: 1});
}
});
return result;
}
function getFirstRepeatingElement(A) {
let array = getCountOccurence(A);
array.some((element)=> {
if (element.count > 1) {
result = element.element;
return true;
}
});
return result;
}

Counting repeated values in array Javascript

I am trying to practice my algorithm skills. I know there is already an algorithm written out there, I just want to try it on my own and see how close i could get.
INPUT:
arr1 = ['asd','ew','lol','asd']
EXPECTED OUTPUT:
{ asd: 2, ew: 1, lol: 1 }
This is my code:
arr1 = ['asd', 'ew', 'lol', 'asd']
arr2 = []
results = {}
function checkIfExists(word) {
if (arr2.length != 0) {
for (i = 0; i < arr2.length; i++) {
if (arr2[i] == word) {
results[word] += 1
} else {
arr2.push(word)
results[word] = 1
}
}
} else {
arr2.push(word)
results[word] = 1
}
}
for (i = 0; i < arr1.length; i++) {
checkIfExists(arr1[i])
}
console.log(results)
ACTUAL OUTPUT:
{ asd: 2, ew: 2 }
You used i as a global variable, so don't use for two loop. Other mistake is in your increment algorithm that add more than needed count to results array. So try it:
arr1 = ['asd','ew','lol','asd']
arr2 = []
results = {}
function checkIfExists(word){
if (arr2.length != 0){
var exists = false;
for (var j = 0; j < arr2.length; j++){
if(arr2[j] == word){
results[word] += 1
exists = true;
break;
}
}
if(!exists) {
arr2.push(word)
results[word] = 1
}
}else{
arr2.push(word)
results[word] = 1
}
}
for (var i = 0; i < arr1.length; i++) {
checkIfExists(arr1[i])
}
console.log(results)
There are three questions I identified immediately which you might have intended to ask.
What's wrong with my code?
I couldn't phrase this better than Felix Klings comment:
The first problem is that you are not using var to declare i.
The loop presumably intended to locate an item within arr2 also modifies arr2... a lot!
Why is my code producing incorrect output? Your code is actually producing correct output for the logic it expresses. I suspect the issue is that the logic it expresses doesn't match the logic you intended to express. This isn't uncommon
How do I fix my code?
Start by changing your loop idioms from for (i = ...) to for (var i = ...).
Think about the purpose of that loop. If it's intended to locate an item within arr2, then it shouldn't need to modify arr2 to do so. Perhaps you don't need the loop;
You could probably use Array.prototype.indexOf or Array.prototype.includes in place of that entire loop!
You could probably use function checkIfExists(word) { results[word] = arr1.filter(function(w) { return w === word; }).length; } in place of that entire function!
It seems like you could use some higher-level awareness when designing functions, so perhaps it might be a good idea to try to wrap your head around some of the elements in this code:
var arr1 = ['asd','ew','lol','asd'];
var result = arr1.reduce(function(result, w) { result[w] = result[w] || 0;
result[w]++;
return result; }, {}));
console.log(result);

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]);
}
}
}

Categories