Related
I have two arrays:
var array1= [1,3,5,7,9,11]
var array2= [undefined,4,6]
I need to merge one element of the array1, then one element of the array2, etc. This is my code:
function mergeArrays(array1, array2){
var array3 = [];
maxlength = Math.max(array1.length, array2.length);
for(i=0;i<maxlength;i++){
array3.push(array1[i]);
array3.push(array2[i]);
}
return console.log(array3);
}
The output now is:
array3 = [1,undefined,3,4,6,7,undefined,9,undefined,11,undefined]
I need the output to be:
array3 = [1,undefined,3,4,6,7,8,11]
I mean, I can't use ( != undefined), because if I have an undefined in the middle of the array it has to be there.
You are not placing a check for the length of shorter array.
Your function is fetching a value which is higher than the length of the array, hence, extra undefined. This should do the job
var array1 = [1, 3, 5, 7, 9, 11];
var array2 = [undefined, 4, 6];
function mergeArrays(array1, array2) {
var array3 = [];
maxlength = Math.max(array1.length, array2.length);
for (i = 0; i < maxlength; i++) {
if (i < array1.length) array3.push(array1[i]);
if (i < array2.length) array3.push(array2[i]);
}
return console.log(array3);
}
mergeArrays(array1, array2);
You can grab the max length of the two arrays and loop until you hit that value. While looping, check if the length has been exceeded and push onto the result.
const allEqual = (...args) =>
((head, ...tail) => tail.every(curr => curr === head))
(args.map(v => JSON.stringify(v)));
const test = ({ actual, expected }) => {
console.log(JSON.stringify(actual));
console.log(allEqual(actual, expected));
};
const interlaceArrays = (...arrays) => {
const result = [];
const maxLen = Math.max(...arrays.map(({ length }) => length));
for (let i = 0; i < maxLen; i++) {
arrays.forEach(arr => {
if (i < arr.length) result.push(arr[i]);
})
}
return result;
};
const
odd = [1, 3, 5, 7, 9, 11],
even = [undefined, 4, 6],
other = ['a', 'b'];
test({
actual: interlaceArrays(odd, even),
expected: [1, undefined, 3, 4, 5, 6, 7, 9, 11]
});
test({
actual: interlaceArrays(odd, even, other),
expected: [1, undefined, 'a', 3, 4, 'b', 5, 6, 7, 9, 11]
});
.as-console-wrapper { top: 0; max-height: 100% !important; }
I have an array a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7]
I want to fetch all the duplicate pair in this array list.
Since there are pairs of 2 and 7 the output should be -
Output: [2, 7]
I tried writing my own logic but I am very weak in that area. Can somebody help?
function getDuplicateArrayElements(arr){
let sorted_arr = arr.slice().sort();
let results = [];
for (let i = 0; i < sorted_arr.length; i++) {
let matchingElementCount = 1;
for (let j = i + 1; j < sorted_arr.length - i; j++) {
if (sorted_arr[j] === sorted_arr[i]) {
++matchingElementCount;
} else {
if(matchingElementCount % 2 === 0) {
results.push(sorted_arr[i]);
}
i = j - 1;
break;
}
}
}
return results; } var a = [1,1,1,2,2,3,3,3,4,6,6,6,7,7]; var duplicateValues= getDuplicateArrayElements(a);
You can achieve your result by using reduce and forEach.
const arr = [1,1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];
// Generate a hashmap from the given array for counting the frequency.
const hashMap = arr.reduce((a, c) => {
a[c] = (a[c] || 0) + 1;
return a;
}, {});
const pair = [];
// If the frequency is divided by 2 then push the key of the hashMap into pair array.
Object.entries(hashMap).forEach(([k, v]) => {
if (v % 2 === 0) {
[...Array(Math.floor(v / 2))].forEach(_ => pair.push(k));
}
})
console.log(pair);
You can grab the frequency of each number, and then filter out any which have an odd frequency. You can then .flatMap() the frequencies to an array containing your number for each pair you found like so:
const a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];
const freq = a.reduce((m, n) => m.set(n, (m.get(n) || 0) + 1), new Map);
const res = [...freq].filter(([n, count]) => count % 2 == 0).flatMap(([n, c]) => Array(c/2).fill(n));
console.log(res);
This way, if you have four 1s (ie: two pairs of 1s), the filter will pick up on that, allowing you to flat-map the [1, 4] array to an array of [1, 1], which is merged into the larger resulting array.
You could create a helper map and keep the counts of each number as the values and the numbers itself as the keys. After iterating through the array, you only need to find the ones with a count divisible by 2:
var a = [1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 7, 7]
function findDuplicates(arr) {
const map = {};
for (const curr of arr) {
if (!map[curr]) {
map[curr] = 0;
}
map[curr]++;
}
const res = [];
for (const key in map) {
if (map.hasOwnProperty(key) && map[key] % 2 === 0) {
res.push(Number.parseInt(key));
}
}
return res;
}
console.log(findDuplicates(a));
You can first count the occurrence of each numbers and if it is greater than 0 and divisible by 2 then add these to final result else don't
function getDuplicateArrayElements(arr) {
let map = {}
let results = [];
for (let num of arr) {
map[num] = map[num] || 0
map[num]++
}
return Object.keys(map)
.filter(v => map[v] && map[v] % 2 === 0)
.map(v => new Array(map[v]/2).fill(+v))
.flat()
.sort()
}
var a = [1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 7, 7,8,8,8,8];
var duplicateValues = getDuplicateArrayElements(a);
console.log(duplicateValues)
const a = {};
[1,1,1,2,2,3,3,3,4,6,6,6,7,7].forEach(v => {a[v] = a[v] ? a[v] + 1 : 1});
const l = [];
Object.keys(a).forEach(k => !(a[k] % 2) && l.push(k));
Here you go:
function getDuplicateArrayElements(arr){
var dupilcates=arr.filter(x => arr.filter(y=>y==x).length==2);
var found=[];
for(var i=0;i<dupilcates.length;i=i+2)
found.push(dupilcates[i]);
return found;
}
This will give you the desired pairs. with [1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 6, 7, 7] input it will return [1,1,2,6,6,7]:
function getDuplicateArrayElements(arr){
let sorted_arr = arr.slice().sort();
let results = [];
let i = 0;
while (i < sorted_arr.length) {
let counter = 1;
let j = i;
while (sorted_arr[j] === sorted_arr[j+1]) {
counter++;
j++;
}
if (counter%2 == 0) {
results.push(...Array(counter/2).fill(sorted_arr[i]))
}
i += counter;
}
return results;
}
var a = [1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 6, 7, 7];
console.log(getDuplicateArrayElements(a));
Another rather concise solution:
a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];
uniques = new Set(a); //filter out duplicates
res = [];
uniques.forEach((key)=>{
if(a.filter(elem => elem === key).length === 2){res.push(key)};
//filter out only the elements which match the key being tested
//if there are 2, push to result
})
Edit: even more concise, but perhaps less efficient:
a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];
res = Array.from(new Set(a.filter(elem => a.filter(el => el === elem).length === 2)));
Javascript has awesome JSON object, in my opinion, you can use json as a dictionary;
{ key: _value }.
Loop throw array one times, no sort, no slice
key is array's element value, _value is frequency
var frequencies = {};
for (let i = 0; i < a.length; a++) {
if (result[a[i]] == 'over') continue;
if (result[a[i]] == undefined) { // First times
result[a[i]] = 1
} else if (result[a[i]] == 1) { // Second times
result[a[i]] = 2
} else { // Ignore if > 2
result[a[i]] = 'over'
}
}
// result: {1: "over", 2: 2, 3: "over", 4: "over", 6: "over", 7: 2}
so now pick keys have value equal 2
function getDuplicateArrayElements(numbers: number[]): number[] {
const occurences = new Map<number, number>();
for (let number of numbers) {
if (occurences.has(number)) {
const current = occurences.get(number)!;
occurences.set(number, current + 1);
} else
occurences.set(number, 1)
}
return (
Array
.from(occurences.entries())
.reduce<number[]>(
(accumulator, [key, value]) => {
if (value === 2) {
return accumulator.concat(key)
}
return accumulator
},
[]
)
)
}
const a = [1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 6, 6, 6, 7, 7];
getDuplicateArrayElements(a); // [2, 7]
I would like to iterate over the array and getting an average from 5 next elements, not from the whole array. I try to do it by code bellow, but it doesn´t work. I appreciate any kind of help or suggestions.
function standardDeviation(array) {
let newArray = [];
for (let i = 0; i < array.length; i++) {
let tempArray = [];
const arrAvg = tempArray =>
tempArray.reduce((a, b) => a + b, 0) / tempArray.length;
newArray += tempArray;
for (let j = array[i]; (j = array[i + 5]); i++) {
tempArray += array[j];
}
}
console.log(newArray);
return newArray;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
standardDeviation(arr);
You could slice a given array and take only five elements for getting an average.
function standardDeviation(array) {
const arrAvg = tempArray => tempArray.reduce((a, b) => a + b, 0) / tempArray.length;
return array.map((_, i, a) => arrAvg(a.slice(i, i + 5)));
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(standardDeviation(arr));
You could try using the slice() function of array element.
// simulated loop index
var curr_index_pos = 3;
// entire array
var array_full = [1,2,3,4,5,6,7,8,9,10];
// array with 5 next values from "curr_index_pos"
var array_5 = array_full.slice(curr_index_pos,curr_index_pos+5);
var sum = 0;
for( var i = 0; i < array_5.length; i++ ) {
sum += parseInt( array_5[i] );
}
var avg = sum/array_5.length;
console.log("array_5", array_5);
// [4,5,6,7,8]
console.log("sum", sum);
// 30
console.log("avg", avg);
// 6
Trying my best, but still not able to log the result at the end.
var arr = [2, 2, 2, 2, 2, 4, 5, 5, 5, 9];
function foo(arr) {
var a = [], b = [], prev;
arr.sort();
for ( var i = 0; i < arr.length; i++ ) {
if ( arr[i] !== prev ) {
a.push(arr[i]);
b.push(1);
} else {
b[b.length-1]++;
}
prev = arr[i];
}
return [a, b];
}
var result = foo(arr);
var a = result[0]
var b = result[1]
var aa=a.split(",");
var ab=b.split(",");
var a = a.split(",").length;
var b = b.split(",").length;
for (c = 0; c < a; c++){
console.log(aa[c]);
console.log(ab[c]);}
I want to get values from two array result[0] and result[1] one by one in the loop.
Right now I am able to get all the values comma separated but when I split values, nothing shows up.
You were almost there:
var arr = [2, 2, 2, 2, 2, 4, 5, 5, 5, 9];
function foo(arr) {
var a = [], b = [], prev;
arr.sort();
for ( var i = 0; i < arr.length; i++ ) {
if ( arr[i] !== prev ) {
a.push(arr[i]);
b.push(1);
} else {
b[b.length-1]++;
}
prev = arr[i];
}
return [a, b];
}
var result = foo(arr);
var a = result[0]
var b = result[1]
for (i=0; i<a.length; i++){
console.log("Number: " + a[i] + "; Time repeated:"+ b[i]); }
You can create an empty object to track the number of repetitions & an array to hold only unique values.Use indexOf to find if element already exist in uniqArray.
var arr = [2, 2, 2, 2, 2, 4, 5, 5, 5, 9];
var repCount = {}, // to track number of repetitions
uniqArray = []; // holds only unique values
arr.forEach(function(item) {
if (uniqArray.indexOf(item) == -1) {
// id item is not present push it
uniqArray.push(item)
}
// check if the object already have a key for example 2,4,5,9
if (!repCount.hasOwnProperty(item)) {
repCount[item] = 1 // if not then create new key
} else {
// if it is there then increase the count
repCount[item] = repCount[item] + 1
}
})
console.log(uniqArray, repCount)
Looking at your comment...
So basically i want to get the unique no. from array and the no. of repetition of that particular value into another variable
You can achieve this by using reduce function
var arr = [2, 2, 2, 2, 2, 4, 5, 5, 5, 9];
var a = arr.reduce(function (acc, next) {
acc[next] = acc[next] ? acc[next] + 1 : 1;
return acc;
}, {});
console.log(a);
which gives you a hash with unique numbers as keys and their counts as values. From here you can easily break it into two arrays if you really need to..
I have an array here:
var myArr = [1, 1, 2, 5, 5, 7, 8, 9, 9];
Now I want to remove both appearances of a duplicate. So the desired result is not:
var myArr = [1, 2, 5, 7, 8 ,9];
but
var myArr = [2, 7, 8];
Basically I know how to remove duplicates, but not in that that special way. Thats why any help would be really appreciated!
Please note: My array is filled with strings. The numbers here were only used as an example.
jsfiddle for this code:
var myArr = [1, 1, 2, 5, 5, 7, 8, 9, 9];
var newArr = myArr;
var h,i,j;
for(h = 0; h < myArr.length; h++) {
var curItem = myArr[h];
var foundCount = 0;
// search array for item
for(i = 0; i < myArr.length; i++) {
if (myArr[i] == myArr[h])
foundCount++;
}
if(foundCount > 1) {
// remove repeated item from new array
for(j = 0; j < newArr.length; j++) {
if(newArr[j] == curItem) {
newArr.splice(j, 1);
j--;
}
}
}
}
Here's my version
var a = [1, 1, 2, 5, 5, 7, 8, 9, 9];
function removeIfduplicate( arr ) {
var discarded = [];
var good = [];
var test;
while( test = arr.pop() ) {
if( arr.indexOf( test ) > -1 ) {
discarded.push( test );
continue;
} else if( discarded.indexOf( test ) == -1 ) {
good.push( test );
}
}
return good.reverse();
}
x = removeIfduplicate( a );
console.log( x ); //[2, 7, 8]
EDITED with better answer:
var myArr = [1, 1, 2, 5, 5, 7, 8, 9, 9];
function removeDuplicates(arr) {
var i, tmp;
for(i=0; i<arr.length; i++) {
tmp = arr.lastIndexOf(arr[i]);
if(tmp === i) {
//Only one of this number
} else {
//More than one
arr.splice(tmp, 1);
arr.splice(i, 1);
}
}
}
Using Hashmap
create hashmap and count occurencies
filter where hashmap.get(value) === 1 (only unique values)
const myArray = [1, 1, 2, 5, 5, 7, 8, 9, 9];
const map = new Map();
myArray.forEach(v => map.set(v, map.has(v) ? map.get(v)+1 : 1));
myArray.filter(v => map.get(v) === 1);
Old version (slower but valid too)
Heres a short version using Array.filter(). The trick is to first find all values that are NOT uniqe, and then use this array to reject all unique items in the original array.
let myArr = [1, 1, 2, 5, 5, 7, 8, 9, 9];
let duplicateValues = myArr.filter((item, indx, s) => s.indexOf(item) !== indx);
myArr.filter(item => !duplicateValues.includes(item));
// => [2, 7, 8]
Wherever removing duplicates is involved, it's not a bad idea to use a set data structure.
JavaScript doesn't have a native set implementation, but the keys of an object work just as well - and in this case help because then the values can be used to keep track of how often an item appeared in the array:
function removeDuplicates(arr) {
var counts = arr.reduce(function(counts, item) {
counts[item] = (counts[item] || 0) + 1;
return counts;
}, {});
return Object.keys(counts).reduce(function(arr, item) {
if (counts[item] === 1) {
arr.push(item);
}
return arr;
}, []);
}
var myArr = [1, 1, 2, 5, 5, 7, 8, 9, 9];
console.log(removeDuplicates(myArr), myArr);
Check out the example on jsfiddle.
Alternately, you could not use calls to reduce(), and instead use for and for(item in counts) loops:
function removeDuplicates(arr) {
var counts = {};
for(var i=0; i<arr.length; i++) {
var item = arr[i];
counts[item] = (counts[item]||0)+1;
}
var arr = [];
for(item in counts) {
if(counts[item] === 1) {
arr.push(item);
}
}
return arr;
}
Check out the example on jsfiddle.
If it's just alphanumeric, duplicates are case-sensitive, and there can be no more than two of any element, then something like this can work:
var a = [2, 1, "a", 3, 2, "A", "b", 5, 6, 6, "B", "a"],
clean_array = $.map(a.sort(), function (v,i) {
a[i] === a[i+1] && (a[i] = a[i+1] = null);
return a[i];
});
// clean_array = [1,3,5,"A","B","b"]
In this example,we are taking two arrays as function arguments, from this we are going to print only unique values of both arrays hence deleting the values that are present in both arrays.
first i am concatenating both the arrays into one. Then I taking each array value at a time and looping over the array itself searching for its no of occurrence. if no of occurrence(i.e.,count) equal to 1 then we are pushing that element into the result array. Then we can return the result array.
function diffArray(arr1, arr2) {
var newArr = [];
var myArr=arr1.concat(arr2);
var count=0;
for(i=0;i<myArr.length;i++){
for(j=0;j<myArr.length;j++){
if(myArr[j]==myArr[i]){
count++;
}
}
if(count==1){
newArr.push(myArr[i]);
}
count=0;
}
return newArr;
}
EDIT: Here is the jspref http://jsperf.com/deleting-both-values-from-array
http://jsfiddle.net/3u7FK/1/
This is the fastest way to do it in two passes without using any fancy tricks and keeping it flexible. You first spin through and find the count of every occurance and put it into and keyvalue pair. Then spin through it again and filter out the ones where the count was greater than 1. This also has the advanatage of being able to apply other filters than just "greater than 1"; as well as the having the count of occurances if you needed that as well for something else.
This should work with strings as well instead of numbers.
http://jsfiddle.net/mvBY4/1/
var myArr = [1, 1, 2, 5, 5, 7, 8, 9, 9];
var map = new Object();
for(var i = 0; i < myArr.length; i++)
{
if(map[myArr[i]] === undefined)
{
map[myArr[i]] = 1;
}
else
{
map[myArr[i]]++;
}
}
var result = new Array();
for(var i = 0; i < myArr.length; i++)
{
if(map[myArr[i]] > 1)
{
//do nothing
}
else
{
result.push(myArr[i]);
}
}
alert(result);
You can use Set (available in IE 11+) as below
const sourceArray = [1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8];
const duplicatesRemoved = new Set();
sourceArray.forEach(element => {
if (duplicatesRemoved.has(element)) {
duplicatesRemoved.delete(element)
} else {
duplicatesRemoved.add(element)
}
})
console.log(Array.from(duplicatesRemoved))
N.B. Arrow functions are not supported in older browsers. Use normal function syntax for that instead. However, Array.from can easily be polyfilled for older browsers.
Try it here.