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 a problem needing two arrays containing some similar values and different values. I need to concat the arrays into a new array and remove the similar values only showing the individual values. something like arr1 = [1, 44, 2, 3, 5], arr2 = [33, 1, 2, 3, 4, 5], arr3 = [], return arr3 [44, 33, 4]. I have tried a few different ways with no success, one using a nested for loop and the other using .filter(). Any thoughts on how I can solve this? Here is my code:
const arrayDiffs = (arr1, arr2) => {
let arr3 = [];
for (let i = 0; i < arr1.length; i++) {
if (arr3.indexOf(arr1[i]) === -1) {
arr3.push(arr1[1]);
}
for (let n = 0; n < arr2.length; n++) {
if (arr3.indexOf(arr2[n]) === -1) {
arr3.push(arr2[n]);
}
}
return arr3;
};
}
console.log(arrayDiffs([1, 44, 2, 3, 5], [33, 1, 2, 3, 4, 5]));
I have also tried this way:
let arr3 = [];
const arrayDiffs = (arr1, arr2) => {
arr3 = arr1.concat(arr2);
arr3 = arr3.filter(function(item, index) {
if(arr3.indexOf(item) == index){
return true;
}
return false;
});
}
console.log(arrayDiffs([1, 44, 2, 3, 5], [33, 1, 2, 3, 4, 5]));
const myFunc = (a,b) => {
const a_but_not_b = a.filter(x=>!b.includes(x));
const b_but_not_a = b.filter(x=>!a.includes(x));
return [...a_but_not_b,...b_but_not_a];
}
console.log(myFunc([1,2,3],[2,3,4]));
But, let me explain more:
Use filter and includes to get difference.
Last I concat the arrays using spread operator [...a,...b].
Using your first method only we can achieve this. You have to do the following modifications.
for (let i = 0; i < arr1.length; i++) {
if (arr2.indexOf(arr1[i]) === -1) { // first compare the value with arr2 and arr1 and push the non-available values into arr3
arr3.push(arr1[i]);
}
}
for (let n = 0; n < arr2.length; n++) {
if (arr1.indexOf(arr2[n]) === -1) { //compare the value with arr1 and arr2 and push the non-available values into arr3
arr3.push(arr2[n]);
}
}
const arrayDiffs = (arr1, arr2) => {
let arr3 = [];
for (let i = 0; i < arr1.length; i++) {
if (arr2.indexOf(arr1[i]) === -1) {
arr3.push(arr1[i]);
}
}
for (let n = 0; n < arr2.length; n++) {
if (arr1.indexOf(arr2[n]) === -1) {
arr3.push(arr2[n]);
}
}
return arr3;
}
console.log(arrayDiffs([1, 44, 2, 3, 5], [33, 1, 2, 3, 4, 5]));
Have you tried sets in javassript. I think they are used for storing only unique elements.this will bring down you complexity to O(N), where N is total number of elements in arrays. Example :
const letters = new Set()
[...arr1,...arr2].filter(e=>!(arr1.includes(e)&&arr2.includes(e)))
var arr1 = [1, 44, 2, 3, 5],
arr2 = [33, 1, 2, 3, 4, 5],
arr3 = [...arr1,...arr2]
.filter(e=>!(arr1.includes(e)&&arr2.includes(e)));
console.log(arr3);
So I want to create a function in js which takes two arrays and compare them and give a score depending on how many spots in the two arrays match. Is it right or it's bd written. I am new on coding.
Another problem I have is when I try to execute it on chrome's console. It says that compare is not defined
let score = 0;
function compare(arr1, arr2) {
for (let i = 0; i < arr2.length; i++) {
for (let j = 0; j < arr1.length; j++) {
if(arr1[j] === arr2[i]){
score++;
}
}
}
You can use .reduce() to find count of matched elements:
let arr1 = [1, 2, 3, 4, 5],
arr2 = [3, 4, 5, 6, 7],
compare = (a1, a2) => arr1.reduce((a, c) => a + arr2.includes(c), 0);
console.log(compare(arr1, arr2));
Alternatively, you can use .filter() to find array of matched elements and use its length to determine the count.
let arr1 = [1, 2, 3, 4, 5],
arr2 = [3, 4, 5, 6, 7],
compare = (a1, a2) => arr1.filter(v => arr2.includes(v)).length;
console.log(compare(arr1, arr2));
Docs:
Array.prototype.reduce()
Array.prototype.includes()
Array.prototype.filter()
Arrow Functions
This should work for you:
Updated the code as required by you :
let arr1 = [1, 2, 3, 4];
let arr2 = [3,2,3,4,5];
function compare(arr1,arr2){
let count=0;
const max=arr1.length>arr2.length ? arr2.length : arr1.length;
for(var i=0;i<max;i++){
if(arr1[i]==arr2[i]){
count++;
}
}
return count;
}
console.log(compare(arr1,arr2));
here is my problem: I have 5 arrays of integer like these in javascript:
array1 = [0, 1, 2, 3, 4];
array2 = [9, 1, 2, 3, 4];
array3 = [10, 1, 2, 11, 4];
array4 = [12, 1, 2, 13, 4];
array5 = [14, 1, 2, 15, 4];
I have to find the longest common subarray. In this case I have to retrieve the following subarray: [1, 2, 4].
For the records, I won't find repetitions inside arrays and my main goal is not execution speed.
thanks
here is the solution using Set in Javascript
var myArray = [array1 , array2 ,array3 , array4 ,array5];
let keys = new Set();
myArray.forEach(arr => arr.forEach(el => keys.add(el) ))
var common = [...keys].filter(key => myArray.every(arr => arr.includes(key)))
console.log(common);
#define MAX(a,b) a>b?a:b
int main(int argc, char* argv[])
{
if(argc < 2)
return -1;
int x = strlen(argv[1])+1;
int y = strlen(argv[2])+1;
int i,j,k,l;
int longest =0;
char* LCS = (char*)malloc(sizeof(char)*MAX(x,y));
int** arr = (int**)malloc(sizeof(int*)*x);
for(i=0;i<=y;i++)
arr[i] =(int*) malloc(sizeof(int)*y);
for(i=0;i<=x;i++)
for(j=0;j<=y;j++)
{
arr[i][j] = 0;
}
for(i=0;i<x;i++)
for(j=0;j<y;j++)
{
if(argv[1][i] == argv[2][j])
arr[i+1][j+1] = arr[i][j]+1;
if(arr[i+1][j+1] > longest)
{
longest =arr[i+1][j+1];
memset(LCS,0,MAX(x,y));
for( k=0,l=i;k<=longest;k++,l--)
LCS[k] = argv[1][l];
}
}
printf(" %s",argv[2]);
for(i=0;i<x;i++)
{
printf("\n%c",argv[1][i]);
for(j=0;j<y;j++)
{
printf("%d",arr[i][j]);
}
}
printf("\nLongest Common Subarray : %s\n",LCS);
return 0;
}
Try this:
var array1 = [0, 1, 2, 3, 4];
var array2 = [9, 1, 2, 3, 4];
var array3 = [10, 1, 2, 11, 4];
var array4 = [12, 1, 2, 13, 4];
var array5 = [14, 1, 2, 15, 4];
// join everything into one array
var all = array1.join(',')+','+array2.join(',')+','+array3.join(',')+','+array4.join(',')+','+array5.join(',');
all = all.split(',');
// get an object with all unique numbers as keys
var keys = {};
for(var i=0; i<all.length; i++) keys[all[i]] = 1;
console.log(keys);
// generate an array with values present in all arrays
var common = [];
for(var x in keys) {
if(array1.indexOf(parseInt(x)) != -1 && array2.indexOf(parseInt(x)) != -1 && array3.indexOf(parseInt(x)) != -1 && array4.indexOf(parseInt(x)) != -1 && array5.indexOf(parseInt(x)) != -1) {
common.push(x);
}
}
console.log(common);
I guess this can give you a good start:
My script will return you an object with the count of each elements. But for now, it takes the first array as base.
var array1 = [0, 1, 2, 3, 4];
var array2 = [9, 1, 2, 3, 4];
var array3 = [10, 1, 2, 11, 4];
var array4 = [12, 1, 2, 13, 4];
var array5 = [14, 1, 2, 15, 4];
var array6 = [13, 1, 2, 18, 4];
var mainArr = [array1, array2, array3, array4, array5, array6]
function getCommonElement(arr){
var subLength = arr[0].length;
var resultArr = new Array();
var ret = new Object();
for(var k=0;k<subLength;k++){
var temp = new Array();
for(var i=0;i<arr.length;i++){
temp.push(arr[i][k]);
}
resultArr.push(temp);
}
for(var i=0;i<arr[0].length;i++){
ret[arr[0][i]+''] = resultArr[i].join('').split(arr[0][i]+'').length - 1;
}
return ret;
}
Cheers.
/**
longest common subarray b/w 2 arrays
a = [2,3,4,5,6,7,8], b = [6,7,8,4,5,2,3]
ans = 6,7,8
basically create a 2d arr and if elements match dp[i][j] = 1 + dp[i-1][j-1];
if dp[i][j] > maxLen, update maxLen and store the index
Now that we have the maxLen, subarray will be from (index - maxLen) till index.
*/
int[] finMaxCommon(int[] a, int[] b){
int m = a.length, n = b.length, maxLen = 0;
int[][] dp = new int[m+1][n+1];
// i want a 0th row why? m->out of bounds; comparing i-1; i->1 then i-1 will be 0
for (int i = 1; i<=m; i++){
for(int j = 1; j<=n; j++){
if(a[i-1] == b[j-1]) {
dp[i][j] = 1 + dp[i-1][j-1];
maxLen = Math.max(maxLen, dp[i][j]);
}
}
}
// endIndex = 6, 3, a[6-3+1], a[6]
return new int[]{a[endIndex-maxLen+1], [endIndex]};
}
dry run
0,6,7,8,4,5,2,3
0, 0 //
2, 1 // (2,2) i = 1, j = 6 1 + dp[0][5]
3, 2 // (3,3) i = 2, j = 7 1 + dp[1][6]
4,
5,
6, 1
7, 2
8, 3
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.