So I have this task to write isUniform() function, which takes an array as an argument and returns true if all elements in the array are identical.
This is what I wrote:
var array = [1, 2, 3, 4];
isUniform(array);
console.log("- - - - - ")
isUniform([1, 1, 1, 1]);
function isUniform(array) {
var counter = 0;
for (var i = 0; i < array.length - 1; i++) {
for (var j = i + 1; j < array.length; j++) {
if (array[i] !== array[j]) {
counter++;
}
}
}
if (counter === 0) {
return true;
}
return false;
}
The thing is, it only prints out - - - - -. Why?
EDIT:
Okay, I thought when you return something, it automatically prints out.
But there is another problem - why does it return true in the first example?
Alright, thank you for your tips. True, I didn't think of the efficiency. Changed to this:
function isUniform(array) {
for (var i = 0; i < array.length - 1; i++) {
if (array[i] !== array[i+1]) {
return false;
}
}
return true;
}
Now it works perfectly, thank you.
You could use ES6 Set and check its size.
const isUniform = arr => new Set(arr).size == 1;
console.log(isUniform([1, 1, 1, 1]))
console.log(isUniform([1, 2, 3, 4]))
You need to display the result of the function.
You could check just every element against the first one end exit early if not equal.
function isUniform(array) {
var i;
for (i = 1; i < array.length; i++) {
if (array[0] !== array[i]) {
return false;
}
}
return true;
}
console.log(isUniform([1, 2, 3, 4]));
console.log(isUniform([1, 1, 1, 1]));
I know it's been answered but you can also make use of every in the following way:
function isUniform(arr){
return arr.every(function(x){return x === arr[0]});
}
console.log(isUniform([1, 2, 3, 4, 5]));
console.log(isUniform([1, 1, 1, 1, 1]));
Related
The input is an array ints [11, 2, 7, 8, 4, 6] and and integer s 10. The function is to output an array with a pair of two numbers from ints which first form a sum of 10. So here the output should be [2, 8], because 2 + 8 = 10. Why does it output empty array? The arrResults was updated in the nested for loop, so why doesn't it show up like that after the final return statement?
function sumPairs(ints, s) {
let arrResults = [];
let sumOfTwo;
for (i = 0; i < ints.length; i++) {
for (j = 0; j < ints.length; j++) {
sumOfTwo = ints[i] + ints[j];
if (sumOfTwo === s) {
arrResults.push(ints[i]);
arrResults.push(ints[j]);
break;
}
}
if (arrResults !== []) {
break;
}
}
return arrResults;
}
console.log(sumPairs([11, 2, 7, 8, 4, 6], 10));
Beside the wrong comparing of an array with another array (without having the same object reference)
a = []
b = []
a === b // false
// other example
a = []
b = a
a === b // true
for checking the length,
a = []
a.length // 0
and by using a nearly quadratic time complexity of n², even with looping
i = 0; i < array.length - 1
j = i + 1; j < array.length
which is more then the half of n², but strill quadratic,
you could take a single loop with an object fo already seen values.
This approach finds the first pair of the array for a certain sum.
function sumPairs(ints, s) {
const needed = {};
for (const value of ints) {
if (needed[value]) return [s - value, value];
needed[s - value] = true;
}
}
console.log(sumPairs([11, 2, 7, 8, 4, 6], 10));
Your code fails because you are checking to see if the array is empty. The problem is that check is never going to be false, so it exits on the first iteration.
console.log([]===[]);
console.log([]!==[]);
So code with changes to improve performance and to exit out
function sumPairs(ints, s) {
let arrResults = [];
let sumOfTwo;
for (let i = 0; i < ints.length; i++) {
for (let j = i + 1; j < ints.length; j++) {
sumOfTwo = ints[i] + ints[j];
if (sumOfTwo === s) {
arrResults.push(ints[i]);
arrResults.push(ints[j]);
break;
}
}
if (arrResults.length) {
break;
}
}
return arrResults;
}
console.log(sumPairs([11, 2, 7, 8, 4, 6], 10));
There is no need to break out twice, just return the array
function sumPairs(ints, s) {
let arrResults = [];
let sumOfTwo;
for (let i = 0; i < ints.length; i++) {
for (let j = i + 1; j < ints.length; j++) {
sumOfTwo = ints[i] + ints[j];
if (sumOfTwo === s) {
return [ints[i], ints[j]];
}
}
}
return null;
}
console.log(sumPairs([11, 2, 7, 8, 4, 6], 10));
let conditon = false
const test = [2, 0, 3, 4, 5, 6, 7]
for (let i = 0; i < 10; i++) {
for (let j = 0; j < test.length; j++) {
if (0 !== test[j]) {
conditon = true;
break;
}else{
conditon = false;
break;
}
}
console.log(conditon)
}
In this loop it console.log true but it should print false when it finds 0 in an array
You are continuously setting condition to true, because e.g. 0 !== 2 evaluates to true. This is the case for every element, except 0. 0 !== 0 which evaluates to false. You need to put an else check in there and set condition to false, then break out so that it doesn't continue and override your value again by setting condition back to true for the next iterations.
let condition = false;
const test = [2, 0, 3, 4, 5, 6, 7]
for (let i = 0; i < 10; i++) {
for (let j = 0; j < test.length; j++) {
if (0 !== test[j]) {
conditon = true;
} else {
conditon = false;
break;
}
}
console.log(conditon)
// Comment this part out if you want it to continue looping without immediately stopping.
// Otherwise the loop ends once it hits 0.
if(!condition)
break;
}
This is not the best way to do this, mind you... I'm just providing you an example on why your code works the way it does.
Here's a simplified version, which you can examine to see how it works, and which you can use as a template for a more complicated version if desired.
let condition;
const nums = [2, 0, 3, 4, 5, 6, 7];
for(let i = 0; i < 2; i++){
for (let num of nums) {
condition = (num !== 0);
console.log(num, condition);
}
console.log("\n--end of outer loop--\n\n");
}
Edit:
From your comment, I gleaned that after each trip through the outer loop, you want to report if any value in the array was zero. If this is what you're looking for, you'd do something like this:
const nums = [2, 0, 3, 4, 5, 6, 7];
for(let i = 0; i < 2; i++){
let noZerosFound = true;
console.log("checking: " + nums);
for (let num of nums) {
if(num === 0){
noZerosFound = false;
// Can include a `break` statement here for better performance
}
}
console.log("noZerosFound: " + noZerosFound);
console.log("\n");
}
And JavaScript arrays also provide some useful built-in methods for this kind of situation. So if you want, you could simply do:
const nums = [2, 0, 3, 4, 5, 6, 7];
for(let i = 0; i < 2; i++){
console.log("checking: " + nums);
// Applies the function `(num) => num !== 0` to each element of `nums`.
// If the result is true for every element, returns true.
// Otherwise, returns false.
const noZerosFound = nums.every( (num) => num !== 0);
console.log("noZerosFound: " + noZerosFound);
console.log("\n");
}
See the .every method and arrow functions on MDN for further explanation.
There are already good answers here. Let me introduce this way as an extra answer.
const test = [2, 0, 3, 4, 5, 6, 7];
console.log(!test.includes(0));
const test2 = [2, 1, 3, 4, 5, 6, 7];
console.log(!test2.includes(0));
.includes()
array.includes(<value>)
.includes() returns true if a given value is in an array, false if not.
!test.includes(0) returns true if 0 is NOT in test. false if 0 IS in test.
I'm trying the following code but it cant seem to work.
These are my tests:
input = 2,1,3,5,3,2expected output = 3;
input = 2,4,3,5,1expected output = -1
input = 2,4,3,5,1,7
Here is the code
function FirstDuplicate(array) {
var a = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3];
var firstDuplicate = "";
for (var i = 0; i < a.length; i++) {
for (var b = i + 1; b < a.length; b++) {
if (a[i] === a[b])
firstDuplicate = a.indexOf(a[i]);
break;
}
}
return firstDuplicate;
}
You can create a an empty Set and keep adding the elements which are already passed to that Set. If a number comes which is already in Set then return it
function FirstDuplicate(array) {
let passed = new Set();
for(let x of array){
if(passed.has(x)) return x;
passed.add(x);
}
return -1;
}
console.log(FirstDuplicate([2,1,3,5,3,2]))
console.log(FirstDuplicate([2,4,3,5,1]))
console.log(FirstDuplicate([2,4,3,5,1,7]))
You could take an object with the value as key and check if the value has been seen before or not.
function getFirstDuplicate(array) {
var seen = Object.create(null),
i = 0,
value;
for (i = 0; i < array.length; i++) {
value = array[i];
if (seen[value]) return value;
seen[value] = true;
}
return -1;
}
console.log(getFirstDuplicate([1, 7, 3, 5, 4, 2, 9, 3]));
console.log(getFirstDuplicate([1, 7, 3, 5, 4, 2, 9, 6]));
We just push stuff into an object while we iterate over the array. On first occurrence we set it to true, if we find a true we know we found the first duplicate.
function f (arr) {
let tmp = {};
return (arr.find(v => (tmp[v] || (tmp[v] = true) && false)) || -1)
}
console.log(f([2,1,3,5,3,2]))
console.log(f([2,4,3,5,1]))
console.log(f([2,4,3,5,1,7]))
I am working on this task where I need to find a number that happens to appear an odd number of times in an array.
I believe I've almost done it, but if some number appears more than once in a row (like 1 in [1,1,3,1,1]), it will always return that number, no matter if it appears an odd number of times or not.
function findOdd(A) {
var a;
var count = 0;
for (var i = 0; i < A.length; i++) {
a = A[i];
for (var l = i + 1; l < A.length; l++) {
if (a == A[l]) {
count++;
}
}
if (!(count % 2)) {
break;
} else {
count = 0;
}
}
return a;
}
console.log(findOdd([ 1, 1, 2, -2, 5, 2, 4, 4, -1, -2, 5 ]));
I've tried to play with adding 1 to count if [i] = [i+1], but it didn't work.
I'd expect output of findOdd([1, 1, 2, -2, 5, 2, 4, 4, -1, -2, 5]) to be -1, but it is 1. The function always returns first number that happens to be equal to next element of an array.
There's no need to reset count or use a break.
function findOdd(A) {
for (var i = 0; i < A.length; i++){
var count = 0;
for (var l = 0; l < A.length; l++) {
if (A[i] === A[l]) count++;
}
if (count % 2 !== 0) return A[i];
}
}
An important thing to note is that the inner loop is not starting at i+1, its starting at the 0. When A[i] matches A[l], we increment count. A number that appears an odd number of times will result in count becoming odd as well and we can return that number.
The following works but I wonder how the performance compares to simply doing for loops. The complexity seems to be the same.
function findOdd(a) {
let m = {};
a.forEach(e => (m[e] in m) ? m[e] += 1 : m[e] = 1);
for (k in m) {
if (m[k] % 2 != 0) return k;
}
}
console.log(findOdd([1, 1, 3, 1, 1]));
console.log(findOdd([1, 1, 2, -2, 5, 2, 4, 4, -1, -2, 5]));
You could count all values first and then get the value with an odd count.
function getOddCount(array) {
var value,
count = {},
k;
for (value of array) count[value] = (count[value] || 0) + 1;
for (k in count) if (count[k] % 2) return +k;
}
console.log(getOddCount([1, 1, 3, 1, 1]));
console.log(getOddCount([1, 1, 2, -2, 5, 2, 4, 4, -1, -2, 5]));
A naive implementation would simply use an object to store the frequency of each element and then iterate over it at the end to find the element that appeared an odd amount of times.
function findOdd(arr) {
const freq = {};
for(const num of arr){
freq[num] = (freq[num] || 0) + 1;
}
return +Object.keys(freq).find(num => freq[num] % 2 == 1);
}
A more efficient implementation could leverage the properties of the bitwise XOR (^), namely the fact that a ^ a == 0 and that the operation is commutative and associative, leading to the solution of applying XOR on each element of the array to obtain the answer.
function findOdd(arr) {
return arr.reduce((a,c)=>a ^ c, 0);
}
I have an array with value, [0,3,4,6,0], How do I validate if the before values is less than the after values?
var array = [0,3,4,6,0];
for(var i = 0; i < array.length; i++){
//if the value of 0 >,3 >,4, > 6
//return false;
}
I need to require the user to enter an ordered sequence of numbers like 5, 4, 3, 2, 1. Hence, I need to validate if the enter is not in an ordered sequence.
A possible solution in ES5 using Array#every
function customValidate(array) {
var length = array.length;
return array.every(function(value, index) {
var nextIndex = index + 1;
return nextIndex < length ? value <= array[nextIndex] : true;
});
}
console.log(customValidate([1, 2, 3, 4, 5]));
console.log(customValidate([5, 4, 3, 2, 1]));
console.log(customValidate([0, 0, 0, 4, 5]));
console.log(customValidate([0, 0, 0, 2, 1]));
Iterate all the array, expect true until you reach a false, where you can break out of the loop.
function ordered(array) {
var isOk = true; // Set to true initially
for (var i = 0; i < array.length - 1; i++) {
if (array[i] > array[i + 1]) {
// If something doesn't match, we're done, the list isn't in order
isOk = false;
break;
}
}
document.write(isOk + "<br />");
}
ordered([]);
ordered([0, 0, 0, 1]);
ordered([1, 0]);
ordered([0, 0, 0, 1, 3, 4, 5]);
ordered([5, 0, 4, 1, 3, 4]);
function inOrder(array){
for(var i = 0; i < array.length - 1; i++){
if((array[i] < array[i+1]))
return false;
}
return true;
}
What you can do is to loop the array and compare adjacent elements like this:
var isOk = false;
for (var i = 0; i < array.length - 1; i++) {
if (array[i] > array[i+1]) {
isOk = true;
break;
}
}
Thus flag isOk will ensure that the whole array is sorted in descending order.