function pairElement(str) {
var arr = [['G','C'],['C','G'],['A','T'],['T','A']],b=[]
for(var k=0;k<arr.length;++k){
var res = arr.filter(function(v){
return v;
})[k][0]
var j=0;
while(j<str.length){
if(str[j]===res){
b.push(arr[k])
}
j++;
}
}
return b;
}
console.log(pairElement("ATCGA"));
I want pairing result in order of the argument passed to the main function. This code's result should be
[['A','T'],['T','A'],['C','G'],['G','C'],['A','T']] but i'm getting as [['G','C'],['C','G'],['A','T'],['A','T'],['T','A']]
Your inner and outer loops are flipped. The outer loop should iterate over the string, and the inner loop should iterate over the array.
function pairElement(str) {
var arr = [['G', 'C'], ['C', 'G'], ['A', 'T'], ['T', 'A']],
b = [];
for (var k = 0; k < str.length; k++) {
for (var j = 0; j < arr.length; j++) {
if (str[k] === arr[j][0]) {
b.push(arr[j]);
}
}
}
return b;
}
console.log(pairElement("ATCGA"));
Your code can also be simplified using an object instead of a 2D array, and with Array#map:
function pairElement(str) {
var pairs = { 'G': 'C', 'C': 'G', 'A': 'T', 'T': 'A' };
return str.split('').map(ch => [ch, pairs[ch]]);
}
console.log(pairElement("ATCGA"));
Related
Objective: Find all sets of length n combinations of m arrays, such that index i of each item in a set is not the same as i in any other element of that set
I have the following arrays:
array1 = ['a', 'b', 'c', 'd'];
array2 = ['e', 'f', 'g', 'h'];
array3 = ['i', 'j', 'k', 'l'];
array4 = ['m', 'n', 'o', 'p'];
I would like to find every possible combination of these taking one element from each array, but then place those combinations into sets such that index i of any element in a given set is different to index i of another element in that same set. For instance, one set could be:
[
{ 1: "a", 2: "e", 3: "i", 4: "m" },
{ 1: "b", 2: "f", 3: "j", 4: "n" },
{ 1: "c", 2: "g", 3: "k", 4: "o" },
{ 1: "d", 2: "h", 3: "l", 4: "p" }
]
as every property '1' is different and taken from array1, every property '2' is different and taken from array2, etc.
Now I need to find every possible one of these.
I've tried looking at this post and implement it by creating combinations of combinations before filtering out everything invalid and cycling through to establish sets, but of course this missed many and took almost an hour to run on this example. Therefore, I need a more systematic approach to speed up the process and make it neater.
You basically want to find every permutation of every array and combine them. This can be done recursively:
function permutate(arr) {
// every array of length one is already permutated
if (arr.length == 1) return [ arr ];
let permutations = [];
for (let i = 0; i < arr.length; i++) {
// Remove the current element and permutate the rest
let sub = permutate(arr.splice(i, 1));
// Insert current element into every permutation
sub = sub.map(x => [arr[i], ...x]);
// Add permutations to list
permutations.push(...sub);
}
return permutations;
}
Next the combine function:
function combine(arrays, current = [], i = 0) {
if (i == arrays.length)
return [ current ];
let values = [];
for (let j = 0; j < arrays[i].length; j++) {
let temp = current.slice();
temp.push(arrays[i][j]);
values.push(...combine(arrays, temp, i + 1));
}
return values;
}
// If you get a call stack size exceeded (stackoverflow) error, you can replace
// this using nested for loops. For instance for 5 arrays with 5 elements each:
let sets = [];
for (let i = 0; i < permutations[0].length; i++) {
for (let j = 0; j < permutations[1].length; j++) {
for (let k = 0; k < permutations[2].length; k++) {
for (let l = 0; l < permutations[3].length; l++) {
for (let m = 0; m < permutations[4].length; m++) {
let set = [];
for (let n = 0; n < 5; n++) {
set.push([ permutations[0][i][n], permutations[1][j][n], permutations[2][k][n], permutations[3][l][n], permutations[4][m][n] ]);
}
sets.push(set);
}
}
}
}
}
By first permutating every array (which results in 24 different permutations for each one), then combining these (which is 24^4=331776 combinations), you'll get everything you need to construct the arrays. Just loop over every combination and put the elements at the same indices into the same set:
let permutations = [ array1, array2, array3, array4 ].map(arr => permutate(arr));
let sets = combine(permutations);
let out = [];
for (let i = 0; i < sets.length; i++) {
let set = [];
for (let j = 0; j < 4; j++) {
set.push([ sets[i][0][j], sets[i][1][j], sets[i][2][j], sets[i][3][j] ]);
}
out.push(set);
}
Working example:
array1 = ['a', 'b', 'c', 'd'];
array2 = ['e', 'f', 'g', 'h'];
array3 = ['i', 'j', 'k', 'l'];
array4 = ['m', 'n', 'o', 'p'];
function permutate(arr) {
if (arr.length == 1) return [ arr ];
let permutations = [];
for (let i = 0; i < arr.length; i++) {
let temp = arr.slice();
temp.splice(i, 1);
let sub = permutate(temp);
sub = sub.map(x => [arr[i], ...x]);
permutations.push(...sub);
}
return permutations;
}
function combine(arrays, current = [], i = 0) {
if (i == arrays.length)
return [ current ];
let values = [];
for (let j = 0; j < arrays[i].length; j++) {
let temp = current.slice();
temp.push(arrays[i][j]);
values.push(...combine(arrays, temp, i + 1));
}
return values;
}
let permutations = [ array1, array2, array3, array4 ].map(arr => permutate(arr));
console.log(permutations);
let sets = combine(permutations);
let out = [];
for (let i = 0; i < sets.length; i++) {
let set = [];
for (let j = 0; j < 4; j++) {
set.push([ sets[i][0][j], sets[i][1][j], sets[i][2][j], sets[i][3][j] ]);
}
out.push(set);
}
console.log(out);
Below is the code I unsuccessfully try to run in the console of chrome. Now the code of which looks like this and does not actually work.
Test.provide = Test.data = function arraaays() {
const c = [];
for (let i = 0; i < Math.max(a.length, b.length); i++) {
if (a[i] !== undefined) {
c.push(a[i]);
}
if (b[i] !== undefined) {
c.push(b[i]);
}
}
console.log(c);
}
The code itself should interact with two arrays that are in Test.data and create a new one of this type on their basis
a: ['a', 'b', 'c'] //first array
b: ['d', 'e'] //second array
c: ['a', 'd', 'b', 'e', 'c'] // new array
function arry(a, b) {
var c = [];
for (let i = 0; i < Math.max(a.length, b.length); i++) {
if (a[i] != undefined) {
c.push(a[i]);
}
if (b[i] != undefined) {
c.push(b[i]);
}
}
return c;
}
Test.provide = arry(Test.data.a, Test.data.b);
So, I am trying to figure out a situation where I would populate an array (b[]) with the index numbers from another array (a[]) whose elements meet a certain criteria (array b would be index numbers based on array a which is an array of images, and would populate b when width is greater than height).
So, I came up with a hypothetical function in hopes of getting an array output where I would get a listing from a[] that align with values from b[]. Needless to say, neither attempt came up with anything of value.
var a = ['ab', 'bc', 'cd', 'de', 'ef', 'fg', 'gh', 'hi'];
var b = [2, 4, 5];
var d = function(a, b) {
var func1 = [];
var func2 = [];
for(i = 0; i > b.length; i++) {
func1.push(a[b[i]]);
}
console.log('func1 = ' + func1); // 'func1 = []'
for(i=0; i > a.length; i++) {
if(b.indexOf(a.indexOf(a[i])) > -1) {
func2.push(a[i])
}
}
console.log('func2 = ' + func2); // 'func2 = []'
}
d(a,b) // Ideally outputs ['cd', 'ef', 'fg']
Is this a matter of function scope, or am I missing the point of .push?
The comparisons in your for loops are backwards. They should be like this:
for(i = 0; i < b.length; i++) {
func1.push(a[b[i]]);
}
console.log('func1 = ' + func1); // 'func1 = []'
for(i=0; i < a.length; i++) {
if(b.index(a.indexOf(a[i])) > 1) {
func2.push(a[i])
}
}
Also, b.index is not a function. I assume you meant indexOf:
var a = ['ab', 'bc', 'cd', 'de', 'ef', 'fg', 'gh', 'hi'];
var b = [2, 4, 5];
var d = function(a, b) {
var func1 = [];
var func2 = [];
for(i = 0; i < b.length; i++) {
func1.push(a[b[i]]);
}
console.log('func1 = ' + func1); // 'func1 = []'
for(i=0; i < a.length; i++) {
if(b.indexOf(a.indexOf(a[i])) > 1) {
func2.push(a[i])
}
}
console.log('func2 = ' + func2); // 'func2 = []'
}
d(a,b) // Ideally outputs ['cd', 'ef', 'fg']
This outputs:
func1 = cd,ef,fg
func2 = fg
use for(i=0; i < a.length; i++) instead! Proper syntax is the key to success! Thanks #Superdrac
I have an array like this:
[1, {a: 'b', c: 'd'}, {c: 'd', a: 'b'}, {e: 'f'}, 'b']
What I want to do is that I want to remove the duplicates from this array whether they are objects or not so that the final array could become this:
[1, {a: 'b', c: 'd'}, {e: 'f'}, 'b']
I have seen many solutions on the site but none works for my issue. How could I do it?
I tried this:
function uniq_fast(a) {
var seen = {};
var out = [];
var len = a.length;
var j = 0;
for(var i = 0; i < len; i++) {
var item = a[i];
if(seen[item] !== 1) {
seen[item] = 1;
out[j++] = item;
}
}
return out;
}
But this removed the third object aswell.
Thanks.
If you just want to compare references and not the object's contents, you can use:
arr.reduce(function(accumulator, element){
if (accumulator.indexOf(element) !== -1) return accumulator;
return accumulator.concat(element);
}, []);
Otherwise, you need to create a function that compares the object's contents, for example:
function objectsMatch(obj1, obj2) {
if (obj1 === obj2) return true;
for (var prop in obj1) {
if (!(prop in obj2) || obj1[prop] !== obj2[prop]) return false;
}
for (var prop in obj2) {
if (!(prop in obj1)) return false;
}
return true;
}
And then use something like:
arr.reduce(function(accumulator, element){
if (accumulator.some(function(otherElement){
return objectsMatch(element, otherElement);
})) return accumulator;
return accumulator.concat(element);
}, []);
This function will do it for you. It uses Object.keys() to cross reference the objects. If seen is populated with a known key and the known key content doubles that of the object in seen, delete property from object. Finally if object is empty delete the whole object from the array using splice. Note this solution only works if all input is like the provided sample. Else the function needs to be written recursively.
var abc = [1, {a: 'b', c: 'd'}, {c: 'd', a: 'b'}, {e: 'f'}, 'b'];
function uniq_fast(a) {
var seen = {};
var deleteObject = [];
var len = a.length;
for(var i = 0; i < len; i++) {
if (Object.prototype.toString.call(a[i]) === '[object Array]' || Object.prototype.toString.call(a[i]) === '[object Object]')
{
var test = Object.keys(a[i]);
var len2 = test.length;
for (var j = 0; j < len2; ++j)
{
if (seen[test[j]] && a[i][test[j]] === seen[test[j]])
{
delete a[i][test[j]];
}
else
{
seen[test[j]] = a[i][test[j]];
}
}
if (Object.keys(a[i]).length == 0)
{
deleteObject.push(i);
}
}
}
for (var i = 0; i < deleteObject.length; ++i)
{
a.splice(deleteObject[i], 1);
}
return a;
}
console.log(uniq_fast(abc));
It is working well is there any other better way to remove duplicates from one array if it has elements of another array ?.
<script>
var array1 = new Array("a","b","c","d","e","f");
var array2 = new Array("c","e");
for (var i = 0; i<array2.length; i++) {
var arrlen = array1.length;
for (var j = 0; j<arrlen; j++) {
if (array2[i] == array1[j]) {
array1 = array1.slice(0, j).concat(array1.slice(j+1, arrlen));
}
}
}
alert(array1);
</script>
array1 = array1.filter(function(val) {
return array2.indexOf(val) == -1;
});
Or, with the availability of ES6:
array1 = array1.filter(val => !array2.includes(val));
filter() reference here
indexOf() reference here
includes() reference here
The trick, for reasons that are beyond me, is to loop the outer loop downwards (i--) and the inner loop upwards (j++).
See the example bellow:
function test() {
var array1 = new Array("a","b","c","d","e","f");
var array2 = new Array("c","e");
for (var i = array1.length - 1; i >= 0; i--) {
for (var j = 0; j < array2.length; j++) {
if (array1[i] === array2[j]) {
array1.splice(i, 1);
}
}
}
console.log(array1)
}
How do I know this? See the below:
for( var i =myArray.length - 1; i>=0; i--){
for( var j=0; j<toRemove.length; j++){
if(myArray[i] === toRemove[j]){
myArray.splice(i, 1);
}
}
}
or
var myArray = [
{name: 'deepak', place: 'bangalore'},
{name: 'chirag', place: 'bangalore'},
{name: 'alok', place: 'berhampur'},
{name: 'chandan', place: 'mumbai'}
];
var toRemove = [
{name: 'deepak', place: 'bangalore'},
{name: 'alok', place: 'berhampur'}
];
for( var i=myArray.length - 1; i>=0; i--){
for( var j=0; j<toRemove.length; j++){
if(myArray[i] && (myArray[i].name === toRemove[j].name)){
myArray.splice(i, 1);
}
}
}
alert(JSON.stringify(myArray));
On that note, would anyone be able to explain why the outer loop needs to be looped downwards (--)?
Good luck!
Using the Set.prototype Constructor: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
let array1 = Array('a', 'b', 'c', 'd', 'e', 'f')
let array2 = Array('c', 'e', 'g')
let concat = array1.concat(array2) // join arrays => [ 'a', 'b', 'c', 'd', 'e', 'f', 'c', 'e', 'g' ]
// Set will filter out duplicates automatically
let set = new Set(concat) // => Set { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }
// Use spread operator to extend Set to an Array
let result = [...set]
console.log(result) // => [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ]
You can try this
array1 = array1 .filter(val => {
return !array2.find((val2)=>{
// console.log({valueID:val.id+":"+val2.id});
return val.id===val2.id
})
});
use Array.splice()
var array1 = ['1', '2', '3', '4', '5'];
var array2 = ['4', '5'];
var index;
for (var i=0; i<array2.length; i++) {
index = array1.indexOf(array2[i]);
if (index > -1) {
array1.splice(index, 1);
}
}
This my solution
array1 = array1.filter(function(val) {
return array2.indexOf(val.toString()) == -1;
});
This is my solution to remove duplicate in ES6.
let foundDuplicate = false;
existingOptions.some(existingItem => {
result = result.filter(item => {
if (existingItem.value !== item.value) {
return item;
} else {
foundDuplicate = true;
}
});
return foundDuplicate;
});
I used this approach because in my case I was having array of objects and indexOf was having problem with it.
window.onload = function () {
var array1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'];
var array2 = ['c', 'h', 'k'];
var array3 = [];
var SecondarrayIndexcount = 0;
for (var i = 0; i < array1.length; i++) {
for (var j = 0; j < array2.length; j++) {
if (array1[i] !== array2[j]) {
if (SecondarrayIndexcount === (array2.length - 1)) {
array3.push(array1[i]);
SecondarrayIndexcount = 0;
break;
}
SecondarrayIndexcount++;
}
}
}
for (var i in array3) {
alert(array3[i]);
}
}
</script>