find all digits in a given Array with javascript - javascript

so I need to find all digits from 1 to 9 in a given array with javascript.
Example
findAllDigits([5175, 4538, 2926, 5057, 6401, 4376, 2280, 6137, 8798, 9083] returns the last number it checked when found all 1 to 9 numbers. which in this case 5057
if a given array don't have all numbers from 1 to 9 then it returns "missing digits".
I don't even know how to approach it, hope you can help.
thanks

You could take a Set and collect all digits/characters of stringified numbers.
For returnung the wanted last number, you could use Array#find and check if the size of the set is ten.
const findAllDigits = array => array.find((digits => value => {
[...value.toString()].forEach(Set.prototype.add, digits);
return digits.size === 10;
})(new Set));
console.log(findAllDigits([5175, 4538, 2926, 5057, 6401, 4376, 2280, 6137, 8798, 9083])); // 5057

let data = [123456789, 41358, 2926, 1017];
let filled = [];
const findAllDigits = (array) => {
for (let index = 0; index < array.length; index++) {
const n = array[index];
let arr = Array.from(String(n), Number);
filled = [...filled, ...arr];
let len = [...new Set(filled)].length;
if (len === 9) return array[index +1];
}
let missing = [];
for (let index = 1; index <= 9; index++) {
if (!filled.includes(index)) {
missing.push(index);
}
}
return Number(missing.toString());
};
console.log(findAllDigits(data));

Related

I have a array of string have to find all the common character present from all strings

I have a array of string.
let arr=["robin","rohit","roy"];
Need to find all the common character present in all the strings in array.
Output Eg: r,o
I have tried to create a function for above case with multiple loops but i want to know what should be the efficient way to achive it.
Here's a functional solution which will work with an array of any iterable value (not just strings), and uses object identity comparison for value equality:
function findCommon (iterA, iterB) {
const common = new Set();
const uniqueB = new Set(iterB);
for (const value of iterA) if (uniqueB.has(value)) common.add(value);
return common;
}
function findAllCommon (arrayOfIter) {
if (arrayOfIter.length === 0) return [];
let common = new Set(arrayOfIter[0]);
for (let i = 1; i < arrayOfIter.length; i += 1) {
common = findCommon(common, arrayOfIter[i]);
}
return [...common];
}
const arr = ['robin', 'rohit', 'roy'];
const result = findAllCommon(arr);
console.log(result);
const arr = ["roooooobin","rohit","roy"];
const commonChars = (arr) => {
const charsCount = arr.reduce((sum, word) => {
const wordChars = word.split('').reduce((ws, c) => {
ws[c] = 1;
return ws;
}, {});
Object.keys(wordChars).forEach((c) => {
sum[c] = (sum[c] || 0) + 1;
});
return sum;
}, {});
return Object.keys(charsCount).filter(key => charsCount[key] === arr.length);
}
console.log(commonChars(arr));
Okay, the idea is to count the amount of times each letter occurs but only counting 1 letter per string
let arr=["robin","rohit","roy"];
function commonLetter(array){
var count={} //object used for counting letters total
for(let i=0;i<array.length;i++){
//looping through the array
const cache={} //same letters only counted once here
for(let j=0;j<array[i].length;j++){
//looping through the string
let letter=array[i][j]
if(cache[letter]!==true){
//if letter not yet counted in this string
cache[letter]=true //well now it is counted in this string
count[letter]=(count[letter]||0)+1
//I don't say count[letter]++ because count[letter] may not be defined yet, hence (count[letter]||0)
}
}
}
return Object.keys(count)
.filter(letter=>count[letter]===array.length)
.join(',')
}
//usage
console.log(commonLetter(arr))
No matter which way you choose, you will still need to count all characters, you cannot get around O(n*2) as far as I know.
arr=["robin","rohit","roy"];
let commonChars = sumCommonCharacters(arr);
function sumCommonCharacters(arr) {
data = {};
for(let i = 0; i < arr.length; i++) {
for(let char in arr[i]) {
let key = arr[i][char];
data[key] = (data[key] != null) ? data[key]+1 : 1;
}
}
return data;
}
console.log(commonChars);
Here is a 1 liner if anyone interested
new Set(arr.map(d => [...d]).flat(Infinity).reduce((ac,d) => {(new RegExp(`(?:.*${d}.*){${arr.length}}`)).test(arr) && ac.push(d); return ac},[])) //{r,o}
You can use an object to check for the occurrences of each character. loop on the words in the array, then loop on the chars of each word.
let arr = ["robin","rohit","roy"];
const restWords = arr.slice(1);
const result = arr[0].split('').filter(char =>
restWords.every(word => word.includes(char)))
const uniqueChars = Array.from(new Set(result));
console.log(uniqueChars);

How do I find two numbers in an array that are equal to a target number

I'm looking to find two numbers in an array that are equal to a particular target number. I thought this would be a simple task using .filter but for some reason my code only works when I'm looking for a target number of 4 but doesn't work for anything else?
What am I missing here?
var numbers2 = [1,2,3,4];
var target = 3;
var found = numbers2.filter((num) => {
return (num + num) !== target;
});
console returns (4) [1,2,3,4] as opposed to 2[1,2].
var numbers = [1,4,3,2,6,8,12,1,1,1,2,3,4];
var target = 3;
var output = [];
// Use a set to remove duplicate numbers
numbers = [...new Set(numbers)]; // Only do this step if you dont want duplicates ( like 2+2 = 4 so if your target was for 2, would not show up in the list )
// Sort the numbers from lowest to highest
numbers.sort( (a,b) =>a-b);
// Get index of first number that matches the target or is greater than the target
let index;
for( let i =0; i < numbers.length; i++) {
if( numbers[i] >= target ) {
index = i;
break;
}
}
// Remove all numbers from the array starting at the previous index as these are not possible to add up with another number to the target
if( index ) {
numbers.splice(index, numbers.length - index );
}
// Loop through the remianing array to get first number
numbers.forEach( ( num1, index1) => {
// Loop through array again to get second number
numbers.forEach( (num2, index2) => {
// Check if number is same is same index as you dont want to add the same value to itself, then check if the 2 numbers equal the target number
if( index1 !== index2 && num1 + num2 === target ) {
// If number already exists in array dont duplicate otherwise add it to the array
if( output.indexOf( num1 ) == -1 ) {
output.push( num1);
}
// If number already exists in array dont duplicate otherwise add it to the array
if( output.indexOf( num2 ) == -1 ) {
output.push( num2);
}
}
});
});
console.log( output);
You could find the array location of your target number through using a array.forEach, array.indexOf(), array.find(), and array.findIndex():
let numbers2 = [1,2,3,4];
let target = 4;
//Using foreach
numbers2.forEach((item, index)=>{
if (item == target){
console.log("Found the target at array location "+index);
}
});
//Or through using indexOf():
console.log("Found the target at array location "+numbers2.indexOf(target));
//Or through using find():
const found = numbers2.find(element => element == target);
console.log("Found "+target+" in the array.");
//Or through findIndex():
const target1 = (a) => a == target;
console.log("Found the target at array location "+numbers2.findIndex(target1));
Assuming:
you only need one pair
[2,2] does not count when your target is 4 (as '2' only appears once in the array)
One way to go is:
let numbers = [1, 2, 3, 4]
let target = 4;
let output = [];
const N = numbers.length
outer: for (let i = 0; i < N; i++) {
for (let j = i + 1; j < N; j++) {
if (numbers[i] + numbers[j] === target) {
output.push(numbers[i], numbers[j])
break outer;
}
}
}
console.log(output); //[1,3]
Edit: even if you want more than one pair, it's easy to modify to get that effect (now the target is 5):
let numbers = [1, 2, 3, 4]
let target = 5;
let output = [];
const N = numbers.length
for (let i = 0; i < N; i++) {
for (let j = i + 1; j < N; j++) {
if (numbers[i] + numbers[j] === target) {
output.push([numbers[i], numbers[j]])
}
}
}
console.log(output); //[[1,4], [2,3]]
This is an ideal case for the humble for loop. Methods like .forEach() will always try to loop over all the elements in an array, but if we order the data before we start the search we can break early and eliminate a lot of searching.
Ergo...
var numbers = [1,2,3,4];
var target = 5;
var output = [];
// Handling ordered data is much faster than random data so we'll do this first
numbers.sort();
// We want to start the inner search part way up the array, and we also want
// the option to break so use conventional for loops.
for (let i = 0; i<numbers.length; i++) {
for (let j=i+1; j<numbers.length;j++) {
// If the total = target, store the numbers and break the inner loop since later numbers
// will all be too large
if ((numbers[i]+numbers[j])===target) {
output.push([numbers[i], numbers[j]]);
break;
}
}
// Stop searching the first loop once we reach halfway, since any subsequent result
// will already have been found.
if (numbers[i]>(target/2)) {
break;
}
}
console.log( output);
It makes very little sense to get an array of single numbers, because you'll get all the numbers except for the last one unless the array starts at zero or there are numbers skipped. So I've written a function that'll return an array of single numbers or an array of expressions (strings).
First, make a copy of the array:
const array = [1, 2, 3, 4]
const copy = array.slice(0);
Next, use .flatMap() for the first set of iterations:
array.flatMap(num => { // This is the outer loop of numbers
If the third parameter expression is undefined it will default to false. Then .filter() the copy array, the criteria being that the number from the outer loop plus the current number of the inner loop equals the target number AND the numbers cannot be identical.
copy.filter(n => n !== num && target === n + num);
/*
Iterations on the first iteration of outer loop
1 + 1, 1 + 2, 1 + 3,...
*/
If expression is true, then use .flatMap() to return an expression (string) of whatever equals the target number or an empty array (which returns as nothing since .flatMap() flattens it's returns by a level). If both numbers are identical an empty array will be returned.
copy.flatMap(n => n === num ? [] :
target === n + num ? `${n} + ${num}` :
[]
);
If expression is true half of the array is returned so that there isn't any reversed dupes (ex. 6+2 and 2+6)
let half = result.length / 2;
result = result.slice(0, half);
const log = data => console.log(JSON.stringify(data));
// [1, 2, 3,...10]
const array10 = [...new Array(10)].map((_, i) => i + 1);
// [0, 2, 4, 6,...18]
const arrayEven = [...new Array(10)].map((_, i) => i * 2);
function operands(array, target, expression = false) {
const copy = array.slice(0);
let result = array.flatMap(num => {
if (expression) {
return copy.flatMap((n, i) =>
num === n ? [] :
target === n + num ? `${n} + ${num}` :
[]
);
}
return copy.filter(n => n !== num && target === n + num);
});
if (expression) {
let half = result.length / 2;
result = result.slice(0, half);
}
return result;
}
// Return as an array of single numbers
log(array10);
log('3: '+operands(array10, 3));
log('8: '+operands(array10, 8));
log('5: '+operands(array10, 5));
log(arrayEven);
log('2: '+operands(arrayEven, 2));
log('8: '+operands(arrayEven, 8));
log('15: '+operands(arrayEven, 15));
log('=======================');
// Return as an array of expressions (string)
log(array10);
log('3: '+operands(array10, 3, true));
log('8: '+operands(array10, 8, true));
log('5: '+operands(array10, 5, true));
log(arrayEven);
log('2: '+operands(arrayEven, 2, true));
log('8: '+operands(arrayEven, 8, true));
log('15: '+operands(arrayEven, 15, true));

how to get the array element which has a maximum length in the given array

I need to get the array element which has maximum length in the given array.
Suppose there is an array:
const a = ["apple","banana","mango","watermelon","grapes"];
Here I need to get watermelon as output because watermelon has the maximum length.
Below is what has been tried
let length7=0;
let maxlength = function fn() {
for (i7=0; i7<a.length; i7++) {
if (a[i7].length > length7) {
length7=a[i7].length
}
};
return length7;
};
console.log(maxlength())
From this I am getting the length of the maximum string(as 10). But I need to get the output as watermelon.
Please explain an optimal solution to the problem.
You could store the longest element in a seperate variable and return that.
let maxlength = function fn() {
let length7 = 0;
let value = "";
for (i7 = 0; i7 < a.length; i7++) {
if (a[i7].length > length7) {
length7 = a[i7].length;
value = a[i7];
}
}
return value;
}
The below solution may be one possible solution to achieve the desired objective.
Code Snippet
const getLongestWordIn = arr => (
arr.reduce(
(acc, word) => (word.length > acc.length ? word : acc),
""
)
);
const a = ["apple","banana","mango","watermelon","grapes"];
console.log(getLongestWordIn(a));
Explanation
Use .reduce to iterate over the array
The aggregator/accumulator named acc is initialized as empty string ""
If the word (being iterated) has length more than acc, then assign that word to acc
Else, simply return acc
You need a way to save the index of the maximum length of the array.
Easiest way is to save the index (i7) in a global variable. Then at the end of the iterations instead of saving the maximum length you will have the index of the item with the maximum lenght. Then you just access it from the array.
An examen of the code:
let maxLengthIndex=0
let maxlength=function fn(){
for(i7=0 ; i7<a.length ; i7++){
if(a[i7].length > a[maxLengthIndex].length){
maxLengthIndex = i7
}
}
return a[maxLengthIndex]
}
You can store the longest string on each iteration and replace it by the next element in the array if it's longer.
const array = ["apple", "banana", "mango", "watermelon", "grapes"];
let longestStr = '';
array.forEach((str) => {
if (str.length > longestStr.length) {
longestStr = str;
}
});
console.log(longestStr);
You can also use reduce function on arrays to return the longest. Documentation for array.reduce()
const longestStr = array.reduce((prev, current) => current.length > prev.length ? current : prev, '');
You need to store either (1) just the element with the maximum length or (2) both the element and it's maximum length. You should also move the current max variable (max7 in your case) inside the function. Putting this together and opting for (2):
function longestElement(arr) {
if (!arr.length) return; // empty array
let longest = arr[0];
for (let i = 1; i < arr.length; i++)
longest = arr[i].length > longest.length ? arr[i] : longest;
return longest;
}
let a=["apple","banana","mango","watermelon","grapes"];
console.log(longestElement(a)); // "watermelon"
If you want to shorten this, you can use reduce:
const longestElement = (arr) => arr.reduce((x, y) => x.length > y.length ? x : y);

How to populate an array with integers

Please, how do you populate an array say ‘num’ with numbers not in a second array say ‘fig’? I’m trying to use a loop to have the values of the already populated array ‘fig’ compared to ‘num’ which is to be populated with integers not found in ‘fig’. I’m a bit confused.
If you need to do an array with n numbers you can use this two ways.
const arrayLength = 100;
const numberArray = [...new Array(arrayLength).keys()]
const anotherWay = new Array(arrayLength).fill().map((_, idx) => idx + 1);
console.log(numberArray, anotherWay)
so to do this we have to do a few things:
1) define an existing array with numbers to avoid
2) define length on new array
3) generate a random number and make it an integer
4) check to see if we need to avoid
5) if it's a new value add it to the second array
var first=[55,45,35,1,2,3,4,5];
var second = [];
var i = 7;
var x;
while (i != 0){
x = ~~(Math.random()*100);
var check = false;
for(let j=0; j<first.length;j++){
if(x == first[j]){
check = true;
}
}
if(!check){
second.push(x);
i--;
}
}
console.log(second);
const fig = [-21, 0, 3, 6, 7, 42]
const min = Math.min(...fig) // or fig[0] if the the array is already sorted
const max = Math.max(...fig) // or fig[fig.length - 1]
const num = Array.from({ length: max - min }, (_, i) => i + min)
.filter(el => !fig.includes(el))
or, saving one loop
const num = Array.from({ length: max - min }).reduce((acc, _, i) => {
const curr = i + min
if (!fig.includes(curr)) {
return acc.concat(curr)
}
return acc
}, [])
This is assuming your range is from the smallest number in fig to the largest in fig.

how to increment interger array by 1

I have an array like so [1,9,9,9,9,9]. I want to increment this array by one and return [2,0,0,0,0,0]. Here's the catch - you can't join() or concat(). You cannot change the array in any way other than adding to it. However, you can reverse it but I'm not sure how much that would help
Also, here are a few other examples;
[1,8,9] => [1,9,0];
[1,2,3,9,1] => [1,2,3,9,2];
[5,7,9,9] => [5,8,0,0];
The result can only return an array with single digits.
Basically, pretend that the array is a single number and you're adding 1 to it. Again, no joining, splitting, turning into a string.. etc.
Ideally, I would like a classic loop solution or possibly a recursion solution. Thank you!
here is my repl.it https://repl.it/#CharChar5/Code-Challenge
Thank you in advance for your help and I'm terribly sorry if my questions title is too long and confusing. I'm certainly working on formatting better questions and building a stronger rep on SO.
https://repl.it/#CharChar5/Code-Challenge
Currently this is my code:
jjChallenge=(j)=>{
const len = j.length;
const newArray = [];
for(var i = 0; i<j.length; i++){
if (j[i] == 9) {
if(j[i-1] == 9) {
n = 0;
} else {
newArray[i-1] = newArray[i-1] + 1;
n = 0;
}
newArray.push(n);
} else {
newArray.push(j[i]);
}
}
console.log(newArray)
}
jjChallenge([2,9,9,9]) //works and returns [3,0,0,0]
//[2,9,8,9] doesnt work and returns [3,0,9,0]
Reverse it and increment with carry and then reverse it back
Something like
eg
function incrementIntArray(arr) {
var reverseArray = arr.reverse();
var newReverseArray = [];
var carry = false;
for (var i = 0; i < arr.length; i++) {
var curNum = reverseArray[i];
if (i == 0 || carry) curNum++;
if (curNum > 9) {
carry = true;
curNum = 0;
} else {
carry = false;
}
newReverseArray[i] = curNum;
}
return newReverseArray.reverse();
}
var arr1 = [1, 8, 9];
var arr2 = [1, 2, 3, 9, 1];
var arr3 = [5, 7, 9, 9];
console.log(incrementIntArray(arr1)); //outputs [1,9,0]
console.log(incrementIntArray(arr2)); //outputs [1,2,3,9,2]
console.log(incrementIntArray(arr3)); //outputs [5,8,0,0]
Your code was trying to carry, but it's difficult to carry when coming from the top down, hence the reverse and then its easier to carry from bottom up
Here ya go:
jjChallenge=(arr)=>{
newArray=arr.map((element) => {
return element==9?0:element+1
})
return newArray
}
jjChallenge([2,9,9,9])
Just sum the digits up and then plus one. After that, split it.
Simple and Clean that complies with
you can't join() or concat(). You cannot change the array in any way other than adding to it.
addOne = (data) => {
let sum = 0, digit = data.length - 1
data.forEach(n => sum += n * (10 ** digit--))
return (sum + 1).toString().split("")
}
console.log(addOne([1,8,9]))
console.log(addOne([1,2,3,9,1]))
console.log(addOne([5,7,9,9]))

Categories