I have homework to write a function that will be called with 2 parameters:
a is a list of numbers.
amount represents the count of the numbers in the array.
The function should return the number in the list that occurs amount times.
For example , if a = [5,5,5,3,2,1,1], and amount = 2, the function should return 1, because there are only two ones in the array. If amount = 3, the function should return 5 , if amount = 6, the function will return 0 since there are numbers that occur six time.
try this one
var max=3;
var array=[5,5,5,3,2,1,1];
console.log(verify(array,max))
function verify(array,max) {
var match=0;
array.map(obj => {
if(array.filter(x => x === obj).length == max)
match= obj;
});
return match;
}
Here is a way to get the values by count using reduce.
Since there may be more than one element matching the count, or even 0, an array is returned.
reduce is used to build a map (object) of the unique items to their counts. We the find the map entries where the counts match, and the keys (unique items) for these entries are returned.
const count = (arr, num) => {
const count = arr.reduce((count, x) => {
count[x] = (count[x] || 0) + 1;
return count;
}, {});
return Object.entries(count)
.filter(([k, v]) => v === num)
.map(([k, v]) => +k);
}
console.log(count([5,5,5,3,2,1,1], 1)); // [2, 3]
console.log(count([5,5,5,3,2,1,1], 3)); // [5]
console.log(count([5,5,5,3,2,1,1], 5)); // []
make a array of unique values from real array. Then loop though it and filter() real array to check the count of elements.
const array = [5,5,5,3,2,1,1]
function count(arr,amount){
const unique = [...new Set(arr)];
for(let item of unique){
if(arr.filter(num => num === item).length === amount)
return item;
}
return 0;
}
console.log(count(array,1));
console.log(count(array,2));
console.log(count(array,3));
console.log(count(array,4));
console.log(count(array,5));
You should use below code.
#RaviTeja's code is giving max number of array but you dont want it. You want to number which is same quantity with your "amount" parameter.This code provides this for you
function findingAmount() {
var numberContainer = [ 2, 3, 2,5,2,3 ];
console.log(findingAmountImp(numberContainer,1)); // result 5
console.log(findingAmountImp(numberContainer,2)); // result 3
console.log(findingAmountImp(numberContainer,3)); // result 2
}
function findingAmountImp(numbers,amount) {
var count=1;
for (i=0; i<numbers.length; i++) {
for (j=0; j<numbers.length; j++) {
if(i===j){
j=j+1;
if(j<numbers.length){
if(numbers[i] === numbers[j])
{
count++;
}
}else{
for(k=0;k<i;k++){
if(numbers[i] === numbers[k])
{
count++;
}
}
}
}else{
if(numbers[i] === numbers[j])
{
count++;
}
}
}
if( count === amount){
return numbers[i]
}
count=1;
}
}
Related
It is a simple exercise that I am doing for mere practice and leisure, I have done it in various ways but I was wondering if there is an even more practical way or to reduce the lines of code making use of the many methods of JavaScript.
The exercise is about receiving an array (arr) and a number (target) and returning another array with a pair of numbers found in 'arr' whose sum is equal to 'target'.
function targetSum3(arr, target) {
let newArr = [];
let copyArray = arr;
for (let i of copyArray) {
let x = Math.abs(i - target);
copyArray.pop(copyArray[i]);
if (copyArray.includes(x) && (copyArray.indexOf(x) != copyArray.indexOf(i))) {
newArr.push(i);
newArr.push(x);
return newArr;
}
}
return newArr;
}
If you are fine with a function that just returns a pair of numbers (the first match so to speak) whose sum equals the targets value, this might be enough:
function sumPair (arr, target) {
while(arr.length) {
let sum1 = arr.shift();
let sum2 = arr.find(val => sum1 + val === target);
if (sum2) return [sum2, sum1];
}
return null;
}
const targetSum = (arr, target) => {
const first = arr.find((v,i,a) => arr.includes(target-v) && (arr.indexOf(target-v) !== i));
return first ? [first, target - first] : null;
};
const values = [1,2,3,4,5,6,7,8,9];
console.log(targetSum(values, 1)); // null
console.log(targetSum(values, 2)); // null
console.log(targetSum(values, 3)); // [1, 2]
console.log(targetSum(values, 15)); // [6, 9]
console.log(targetSum(values, 20)); // null
I changed for loop with forEach (more efficient) and there is no need for the copyArray array so I removed it. I also changed pop() with shift(), I think you want to shift the array and not pop-it (if I understand the task correctly).
function targetSum3(arr, target) {
let newArr = [];
arr.forEach(element => {
let x = Math.abs(element - target); // calc x
arr.shift(); // removes first element from arr (current element)
if (arr.includes(x) && (arr.indexOf(x) != arr.indexOf(element))) {
newArr.push(element);
newArr.push(x);
return;
}
});
return newArr;
}
use Array.filter to find the target sum for all values in an given array. See comments in the snippet.
sumsForTargetInArray();
document.addEventListener(`click`,
evt => evt.target.id === `redo` && sumsForTargetInArray());
function sumsInArray(arr, target) {
// clone the array
const clone = arr.slice();
let result = [];
while (clone.length) {
// retrieve the current value (shifting it from the clone)
const current = clone.shift();
// filter arr: all values where value + sum = target
const isTarget = arr.filter(v => current + v === target);
// add to result.
// Sorting is to prevent duplicates later
if (isTarget.length) {
result = [...result, ...isTarget.map(v => [current, v].sort())];
}
}
// weed out duplicates (e.g. 0 + 3, 3 + 0)
const unique = new Set();
result.forEach(r => unique.add(`${r[0]},${r[1]}`));
// return array of array(2)
return [...unique].map(v => v.split(`,`).map(Number));
}
function sumsForTargetInArray() {
const testArr = [...Array(20)].map((_, i) => i);
const target = Math.floor(Math.random() * 30);
document.querySelector(`pre`).textContent = `testArray: ${
JSON.stringify(testArr)}\ntarget: ${target}\nResult: ${
JSON.stringify(sumsInArray(testArr, target))}`;
}
<pre></pre>
<button id="redo">Again</button>
Let's assume that I have ;
var array = [1,2,3,4,4,5,5];
I want it to be;
var newArray = [1,2,3];
I want to remove the duplicates completely rather than keeping them as unique values. Is there a way achieve that through reduce method ?
You could use Array#filter with Array#indexOf and Array#lastIndexOf and return only the values which share the same index.
var array = [1, 2, 3, 4, 4, 5, 5],
result = array.filter(function (v, _, a) {
return a.indexOf(v) === a.lastIndexOf(v);
});
console.log(result);
Another approach by taking a Map and set the value to false, if a key has been seen before. Then filter the array by taking the value of the map.
var array = [1, 2, 3, 4, 4, 5, 5],
result = array.filter(
Map.prototype.get,
array.reduce((m, v) => m.set(v, !m.has(v)), new Map)
);
console.log(result);
I guess it won't have some remarkable performance, but I like the idea.
var array = [1,2,3,4,4,5,5],
res = array.reduce(function(s,a) {
if (array.filter(v => v !== a).length == array.length-1) {
s.push(a);
}
return s;
}, []);
console.log(res);
Another option is to use an object to track how many times an element is used. This will destroy the array order, but it should be much faster on very large arrays.
function nukeDuplications(arr) {
const hash = {};
arr.forEach(el => {
const qty = hash[el] || 0;
hash[el] = qty+1;
});
const ret = [];
Object.keys(hash).forEach(key => {
if (hash[key] === 1) {
ret.push(Number(key));
}
})
return ret;
}
var array = [1,2,3,4,4,5,5];
console.log(nukeDuplications(array));
A slightly more efficient solution would be to loop over the array 1 time and count the number of occurrences in each value and store them in an object using .reduce() and then loop over the array again with .filter() to only return items that occurred 1 time.
This method will also preserve the order of the array, as it merely uses the object keys as references - it does not iterate over them.
var array = [1,2,3,4,4,5,5];
var valueCounts = array.reduce((result, item) => {
if (!result[item]) {
result[item] = 0;
}
result[item]++;
return result;
}, {});
var unique = array.filter(function (elem) {
return !valueCounts[elem] || valueCounts[elem] <= 1;
});
console.log(unique)
Another option is to use an object to track how many times an element is used. This will destroy the array order, but it should be much faster on very large arrays.
// Both versions destroy array order.
// ES6 version
function nukeDuplications(arr) {
"use strict";
const hash = {};
arr.forEach(el => {
const qty = hash[el] || 0;
hash[el] = qty + 1;
});
const ret = [];
Object.keys(hash).forEach(key => {
if (hash[key] === 1) {
ret.push(Number(key));
}
})
return ret;
}
// ES5 version
function nukeDuplicationsEs5(arr) {
"use strict";
var hash = {};
for (var i = 0; i < arr.length; i++) {
var el = arr[i];
var qty = hash[el] || 0;
hash[el] = qty + 1;
};
var ret = [];
for (let key in hash) {
if (hash.hasOwnProperty(key)) {
if (hash[key] === 1) {
ret.push(Number(key));
}
}
}
return ret;
}
var array = [1, 2, 3, 4, 4, 5, 5];
console.log(nukeDuplications(array));
console.log(nukeDuplicationsEs5(array));
There are a lot of over-complicated, and slow running code here. Here's my solution:
let numbers = [1,2,3,4,4,4,4,5,5]
let filtered = []
numbers.map((n) => {
if(numbers.indexOf(n) === numbers.lastIndexOf(n)) // If only 1 instance of n
filtered.push(n)
})
console.log(filtered)
you can use this function:
function isUniqueInArray(array, value) {
let counter = 0;
for (let index = 0; index < array.length; index++) {
if (array[index] === value) {
counter++;
}
}
if (counter === 0) {
return null;
}
return counter === 1 ? true : false;
}
const array = [1,2,3,4,4,5,5];
let uniqueValues = [];
array.forEach(element => {
if(isUniqueInArray(array ,element)){
uniqueValues.push(element);
}
});
console.log(`the unique values is ${uniqueValues}`);
If its help you, you can install the isUniqueInArray function from my package https://www.npmjs.com/package/jotils or directly from bit https://bit.dev/joshk/jotils/is-unique-in-array.
My answer is used map and filter as below:
x = [1,2,3,4,2,3]
x.map(d => x.filter(i => i == d).length < 2 ? d : null).filter(d => d != null)
// [1, 4]
Object.values is supported since ES2017 (Needless to say - not on IE).
The accumulator is an object for which each key is a value, so duplicates are removed as they override the same key.
However, this solution can be risky with misbehaving values (null, undefined etc.), but maybe useful for real life scenarios.
let NukeDeps = (arr) => {
return Object.values(arr.reduce((curr, i) => {
curr[i] = i;
return curr;
}, {}))
}
I would like to answer my questions with an answer I came up with upon reading it again
const array = [1, 2, 3, 4, 4, 5, 5];
const filtered = array.filter(item => {
const { length } = array.filter(currentItem => currentItem === item)
if (length === 1) {
return true;
}
});
console.log(filtered)
//Try with this code
var arr = [1,2, 3,3,4,5,5,5,6,6];
arr = arr.filter( function( item, index, inputArray ) {
return inputArray.indexOf(item) == index;
});
Also look into this link https://fiddle.jshell.net/5hshjxvr/
My program should be as following:
Input : {1,2,3,2,1,8,-3}, sum = 5
Output should be 3 example combinations ({2,3}, {3,2}, {8,-3}) have sum
exactly equal to 5.
I tried to do it in JavaScript but I'm confused.
function findSubarraySum(arr, sum) {
var res = 0;
var currentSum = 0;
for (var i = 0; i < arr.length; i++) {
currentSum += arr[i];
if (currentSum == sum)
res++;
}
return res;
}
console.log(findSubarraySum([1, 2, 3, 4], 10));
You first need a way to iterate over all the unique ways you can choose a start and and of your subarray boundaries (your slice definition).
In my code below, I use a combinations function to get all possible combinations of two indexes for the array supplied. You could do something else, like a simple doubly nested for loop.
Next you need to take the slice of the array according to the slice definition and reduce the elements into a sum. The Array.prototype.reduce function works well for that.
Finally, you want to include the subArray in the list of results only if the reduced sum matched the desired sum.
// Input : {1,2,3,2,1,8,-3}, sum = 5
const { combinations, range } = (() => {
const _combinations = function*(array, count, start, result) {
if (count <= 0) {
yield [...result]; // Yes, we want to return a copy
return;
}
const nextCount = count - 1;
const end = array.length - nextCount; // leave room on the array for the next remaining elements
for (let i = start; i < end; i += 1) {
// we have already used the element at (start - 1)
result[result.length - count] = array[i];
const nextStart = i + 1; // Always choose the next element from the ones following the last chosen element
yield* _combinations(array, nextCount, nextStart, result);
}
};
function* combinations(array, count) {
yield* _combinations(array, count, 0, Array(count));
}
function* range(l) {
for (let i = 0; i < l; i += 1) {
yield i;
}
}
return {
combinations,
range,
};
})();
const subArraysBy = (predicate, array) => {
const result = [];
for (const [beg, end] of combinations([...range(array.length+1)], 2)) {
const subArray = array.slice(beg, end);
if (predicate(subArray)) {
result.push(subArray);
}
}
return result;
};
const sum = array => array.reduce((sum, e) => sum + e);
console.log(
subArraysBy(
a => sum(a) === 5,
[1, 2, 3, 2, 1, 8, -3],
),
);
References:
MDN: Array.prototype.reduce
MDN: function* -- not required for your solution
Lodash: _.range -- implemented this in my code rather than use the lodash one. They work similarly.
Python Docs: combinations - My combinations implementation is inspired by python itertools.
Let's assume that I have ;
var array = [1,2,3,4,4,5,5];
I want it to be;
var newArray = [1,2,3];
I want to remove the duplicates completely rather than keeping them as unique values. Is there a way achieve that through reduce method ?
You could use Array#filter with Array#indexOf and Array#lastIndexOf and return only the values which share the same index.
var array = [1, 2, 3, 4, 4, 5, 5],
result = array.filter(function (v, _, a) {
return a.indexOf(v) === a.lastIndexOf(v);
});
console.log(result);
Another approach by taking a Map and set the value to false, if a key has been seen before. Then filter the array by taking the value of the map.
var array = [1, 2, 3, 4, 4, 5, 5],
result = array.filter(
Map.prototype.get,
array.reduce((m, v) => m.set(v, !m.has(v)), new Map)
);
console.log(result);
I guess it won't have some remarkable performance, but I like the idea.
var array = [1,2,3,4,4,5,5],
res = array.reduce(function(s,a) {
if (array.filter(v => v !== a).length == array.length-1) {
s.push(a);
}
return s;
}, []);
console.log(res);
Another option is to use an object to track how many times an element is used. This will destroy the array order, but it should be much faster on very large arrays.
function nukeDuplications(arr) {
const hash = {};
arr.forEach(el => {
const qty = hash[el] || 0;
hash[el] = qty+1;
});
const ret = [];
Object.keys(hash).forEach(key => {
if (hash[key] === 1) {
ret.push(Number(key));
}
})
return ret;
}
var array = [1,2,3,4,4,5,5];
console.log(nukeDuplications(array));
A slightly more efficient solution would be to loop over the array 1 time and count the number of occurrences in each value and store them in an object using .reduce() and then loop over the array again with .filter() to only return items that occurred 1 time.
This method will also preserve the order of the array, as it merely uses the object keys as references - it does not iterate over them.
var array = [1,2,3,4,4,5,5];
var valueCounts = array.reduce((result, item) => {
if (!result[item]) {
result[item] = 0;
}
result[item]++;
return result;
}, {});
var unique = array.filter(function (elem) {
return !valueCounts[elem] || valueCounts[elem] <= 1;
});
console.log(unique)
Another option is to use an object to track how many times an element is used. This will destroy the array order, but it should be much faster on very large arrays.
// Both versions destroy array order.
// ES6 version
function nukeDuplications(arr) {
"use strict";
const hash = {};
arr.forEach(el => {
const qty = hash[el] || 0;
hash[el] = qty + 1;
});
const ret = [];
Object.keys(hash).forEach(key => {
if (hash[key] === 1) {
ret.push(Number(key));
}
})
return ret;
}
// ES5 version
function nukeDuplicationsEs5(arr) {
"use strict";
var hash = {};
for (var i = 0; i < arr.length; i++) {
var el = arr[i];
var qty = hash[el] || 0;
hash[el] = qty + 1;
};
var ret = [];
for (let key in hash) {
if (hash.hasOwnProperty(key)) {
if (hash[key] === 1) {
ret.push(Number(key));
}
}
}
return ret;
}
var array = [1, 2, 3, 4, 4, 5, 5];
console.log(nukeDuplications(array));
console.log(nukeDuplicationsEs5(array));
There are a lot of over-complicated, and slow running code here. Here's my solution:
let numbers = [1,2,3,4,4,4,4,5,5]
let filtered = []
numbers.map((n) => {
if(numbers.indexOf(n) === numbers.lastIndexOf(n)) // If only 1 instance of n
filtered.push(n)
})
console.log(filtered)
you can use this function:
function isUniqueInArray(array, value) {
let counter = 0;
for (let index = 0; index < array.length; index++) {
if (array[index] === value) {
counter++;
}
}
if (counter === 0) {
return null;
}
return counter === 1 ? true : false;
}
const array = [1,2,3,4,4,5,5];
let uniqueValues = [];
array.forEach(element => {
if(isUniqueInArray(array ,element)){
uniqueValues.push(element);
}
});
console.log(`the unique values is ${uniqueValues}`);
If its help you, you can install the isUniqueInArray function from my package https://www.npmjs.com/package/jotils or directly from bit https://bit.dev/joshk/jotils/is-unique-in-array.
My answer is used map and filter as below:
x = [1,2,3,4,2,3]
x.map(d => x.filter(i => i == d).length < 2 ? d : null).filter(d => d != null)
// [1, 4]
Object.values is supported since ES2017 (Needless to say - not on IE).
The accumulator is an object for which each key is a value, so duplicates are removed as they override the same key.
However, this solution can be risky with misbehaving values (null, undefined etc.), but maybe useful for real life scenarios.
let NukeDeps = (arr) => {
return Object.values(arr.reduce((curr, i) => {
curr[i] = i;
return curr;
}, {}))
}
I would like to answer my questions with an answer I came up with upon reading it again
const array = [1, 2, 3, 4, 4, 5, 5];
const filtered = array.filter(item => {
const { length } = array.filter(currentItem => currentItem === item)
if (length === 1) {
return true;
}
});
console.log(filtered)
//Try with this code
var arr = [1,2, 3,3,4,5,5,5,6,6];
arr = arr.filter( function( item, index, inputArray ) {
return inputArray.indexOf(item) == index;
});
Also look into this link https://fiddle.jshell.net/5hshjxvr/
Write a function that takes in a list and returns a list with all of the duplicates removed (list will only have unique numbers).
Here's what I have so far:
var lista = [1,4,5,1,1,3,5,6,4,4,3];
function dupRemove (lista) {
//Sort the array in case it isn't sorted
lista.sort();
//Object to store duplicates and unique numbers
var listNumbers = {
"Duplicate Numbers": [],
"Unique Numbers": []
};
for (var i = 0; i < lista.length; i++) {
//check if it is not equal to the index of the array before it and after. if it isn't, that means its unique, push it in the uniques array.
if (lista[i] !== lista[i-1] && lista[i] !== lista[i+1]) {
listNumbers["Unique Numbers"].push(lista[i]);
} else {
listNumbers["Duplicate Numbers"].push(lista[i]);
}
}
return listNumbers;
}
Currently, my solution returns an object with keys with the values of "Duplicates": 1, 1, 1, 3, 3, 4, 4, 4, 5, 5 and "Uniques": 6.
How do I remove the duplicates from duplicates and then join these two keys into a single array?
Thank you.
that answer is seriously over -engineered- all you need to to is push all values into a new array if they are not already in it.
function=removeDups()
{
var lista = [1,4,5,1,1,3,5,6,4,4,3];
var uniqueValues=[];
var duplicateValues=[];
for(i=0;i<lista.length;i++)
{
if(uniqueValues.indexof(lista[i] == -1){uniqueValues.push(lista[i]}else{duplicateValues.push(lista[i]}
}
}
You could just use the default filter method that is on all Arrays
You don't need the sort function either. If the item is already found using the indexOf method it will not be added to the newly returned array created by the filter method
var list = [1,4,5,1,1,3,5,6,4,4,3];
function removeDup (arr) {
return arr.filter(function(item, pos) {
return arr.indexOf(item) == pos;
})
}
var sortedList = removeDup(list).sort(function(a,b){
return a - b
})
document.getElementsByTagName('div')[0].textContent = sortedList
<div></div>
Kind of a non elegant solution but it gives you the two arrays: one with the duplicate values and one with the unique ones. Since you cannot rely on .sort() you can just count things.
Function checkList will give you back those two arrays.
var list = [1,4,5,1,1,3,5,6,4,4,3];
console.log(checkList(list));
function checkList(list) {
var uniques = []; // will be [6]
var dups = []; // will be [1, 4, 5, 3]
var checked = []; // save what you have already checked so far
for(i = 0; i < list.length; i++) {
if(notChecked(list[i], checked)) {
checked.push(list[i]);
if(count(list[i], list) > 1) {
dups.push(list[i]);
} else {
uniques.push(list[i]);
}
}
}
return {dups: dups, uniques: uniques}
}
// count how many num in arr
function count(num, arr) {
var count = 0;
var i;
for(i = 0; i < arr.length; i++) {
if(arr[i] == num) count++;
if(count > 1) return count;
}
return count;
}
// check if num has not been checked
function notChecked(num, arr) {
return (arr.indexOf(num) == -1) ? true : false;
}