dna pairing, pushing array inside an array - javascript

function pair(str) {
var dna = [];
var dnaarr = [];
for(var i = 0; i < str.length; i++) {
if(str[i].indexOf('G') === 0) {
var a = dna.push('C');
}
if(str[i].indexOf('C') === 0) {
var b = dna.push('G');
}
if(str[i].indexOf('A') === 0) {
var c = dna.push('T');
}
if(str[i].indexOf('T') === 0) {
var d = dna.push('A');
}
}
for(var j = 0; j < str.length; j++) {
var e = dnaarr.push(str[j]);
var f = dnaarr.push(dna[j]);
}
return dnaarr;
}
pair("ATGCG");
When I run this code, it returns
[ 'A', 'T', 'T', 'A', 'G', 'C', 'C', 'G', 'G', 'C' ]
I need it to return
[['A', 'T'], ['T', 'A'], ['G', 'C'], ['C','G'], ['G', 'C']]
Could anyone please help me with this code?

Here's a simpler version:
function pair(str)
{
// Array to hold the pairs
var dna = [];
// Loop through the string
for (var i = 0; i < str.length; i++) {
// Switch based on the current letter in the string
// Push an array to dna with the current string and it's pair
// in the case of 'G' the array would be ['G','C']
// dna would then be [['G','C']]
switch(str[i])
{
case "G":
dna.push([str[i],"C"]);
break;
case "C":
dna.push([str[i],"G"]);
break;
case "A":
dna.push([str[i],"T"]);
break;
case "T":
dna.push([str[i],"A"]);
break;
};
}
// return the array
return dna;
}
pair("ATGCG")

It was a problem with your array pushes.
function pair(str) {
var dnaarr = [];
//var dnatot = [];
for(var i = 0; i < str.length; i++) {
var dna = [];
dna.push(str[i]); //pushing current str[i]
if(str[i].indexOf('G') === 0) {
var a = dna.push('C');
}
if(str[i].indexOf('C') === 0) {
var b = dna.push('G');
}
if(str[i].indexOf('A') === 0) {
var c = dna.push('T');
}
if(str[i].indexOf('T') === 0) {
var d = dna.push('A');
}
dnaarr.push(dna); //pushing the array dna to the main array dnaarr
}
return dnaarr;
}
console.log(pair("ATGCG"));

I believe this is very easy to read and understand.
function pairElement(str) {
var pairs = { 'G': 'C', 'C': 'G', 'A': 'T', 'T': 'A' };
return str.split('').map(function(char) {
return [char, pairs[char]];
});
}
pairElement("GCG"); // [['G', 'C'], ['C', 'G'], ['G', 'C']]
EDIT: Code is simplified. On the beginning of the function we create object with possible character pairs. Using split and map array methods, we are pairing every char from str with object pairs.

I found this approach to be the most readable. Explanation in comments
function pairElement(str) {
// base pairs defined by proj requirements
var basePairs = {"A": "T", "T": "A", "C": "G", "G": "C"};
var newGeneCodeArr = [];
for (var i = 0; i < str.length; i++) {
// build individual sequence pair that fits requirements
var newGeneCode = [];
newGeneCode.push(str[i]);
newGeneCode.push(basePairs[str[i]]);
newGeneCodeArr.push(newGeneCode);
}
return newGeneCodeArr;
}

function pairElement(str) {
//convert the string into array of characters
str = str.split('');
//define a multidimensional array to hold pairing
var arr = [];
//using the for loop, we can check for each character
for(var i=0; i<str.length; i++)
{
var tmp = [];
//checking characters and adding pairs inside a tmp array
switch(str[i]){
case 'G':
tmp.push(str[i]);
tmp.push('C');
break;
case 'C':
tmp.push(str[i]);
tmp.push('G');
break;
case 'T':
tmp.push(str[i]);
tmp.push('A');
break;
case 'A':
tmp.push(str[i]);
tmp.push('T');
break;
}
//if tmp has something inside, add it to the multidimensional array
if(tmp.length > 0)
arr.push(tmp);
}
return arr;
}
pairElement("GCG");

Another, probably simpler and cleaner, version of it:
function pair(str) {
var arr = str.split(''),
newArr = [];
arr.forEach(function(e){
if (e == 'A') {
newArr.push([e, 'T']);
} else if (e == 'T') {
newArr.push([e, 'A']);
} else if (e == 'G') {
newArr.push([e, 'C']);
} else {
newArr.push([e, 'G']);
}
});
return newArr;
}
Example:
pair('GATC');
will return:
[['G','C'], ['A','T'], ['T', 'A'], ['C', 'G']]

function pair(str) {
// object of dna paring key, value
var pairing = {
"A": "T",
"T": "A",
"C": "G",
"G": "C"
},
// array to store paired object
final = [];
// make an array by .split and map that array by using the dna paring object
final = str.split('').map(function(val) {
var arr = [];
arr.push(val, pairing[val]);
return arr;
});
// return the array of paired objects
return final;
}

Related

Combination of all possible values from first array?

How do a combine the array of arrays based on the first array1 or basically group by array1.
Below is the four Array, where i have to form objects based on A and then based on B.
var array1=["A","B"];
var array2=["1","2","3", "4"];
var array3=["N","O","P", "Q"];
var array4=["R"];
Below is how i need :
[ {
'take': 'A',
'take2': '1',
'take3': 'N',
'take4': 'R'
}, {
'take': 'A',
'take2': '2',
'take3': 'N',
'take4': 'R'
}, {
'take': 'A',
'take2': '3',
'take3': 'N',
'take4': 'R'
}, {
'take': 'A',
'take2': '4',
'take3': 'N',
'take4': 'R'
}, {
'take': 'A',
'take2': '1',
'take3': 'O',
'take4': 'R'
}]
This is something i have tried, but not sure how can i loop n number of n arrays
var result = array1.reduce( (a, v) =>
[...a, ...array2.map(x=>v+x)],
[]);
here is a keep it simple solution (if you know how many arrays do you have) :
const possibilities = [];
const ar1length = array1.length;
const ar2length = array2.length;
const ar3length = array3.length;
const ar4length = array4.length;
// Not cleanest solution available but it does the job
for ( let i = 0; i < ar1length; i++) {
for (let j = 0; j < ar2length; j++) {
for (let k = 0; k < ar3length; k++) {
for (let l = 0; l < ar4length; l++) {
possibilities.push({
"take": array1[i],
"take1": array2[j],
"take2": array3[k],
"take3": array4[l]
});
}
}
}
}
Oh and if you want an unknown number of arrays, you may add all of these arrays to an array in order to iterate over it I guess
I've written a function for this task a while ago, takes an arbitrary amount of Arrays and non-arrays and computes all possible combinations
var array1 = ["A", "B"];
var array2 = ["1", "2", "3", "4"];
var array3 = ["N", "O", "P", "Q"];
var array4 = ["R"];
console.log(combinations(array1, array2, array3, array4).join("\n"));
function combinations(...columns) {
const state = [], combinations = [state];
let head = null;
for (let column = 0; column < columns.length; ++column) {
let value = columns[column];
if (Array.isArray(value)) {
if (value.length > 1) {
head = {
next: head,
column,
row: 0
};
}
value = value[0];
}
state[column] = value;
}
let todo = head;
while(todo) {
if (++todo.row === columns[todo.column].length) {
todo.row = 0;
state[todo.column] = columns[todo.column][todo.row];
todo = todo.next;
} else {
state[todo.column] = columns[todo.column][todo.row];
combinations.push(state.slice());
todo = head;
}
}
return combinations;
}
.as-console-wrapper{top:0;max-height:100%!important}
Here's a recursive approach which works for every number of arrays, you just have to call combine(array1, array2, ..., arrayn):
var array1=["A","B"];
var array2=["1","2","3", "4"];
var array3=["N","O","P", "Q"];
var array4=["R"];
function combine(arr1, ...arr2) {
if(arr2.length === 0) return Array.from(arr1, (x) => x.reduce((obj, y, i) => (obj[`take${i}`] = y, obj), {}));
return combine(arr1.flatMap(d => arr2[0].map(v => {
return [...Object.values(d), ...Object.values(v)]
})), ...arr2.slice(1));
}
console.log(combine(array1, array2, array3, array4));

How to get index of an item from nested array

How to get the index of an item from the nested array but don't know how deep is nested
for example
arr=[a,[b,[c],[d],e],f,[g],h]
If I understand your question correctly you are trying to get the index of for example value g.
I created a little script that iterates trough the array, and possibly nested arrays, and if found the correct value returns the index.
Here is a screenshot of the array with the keys that the function getIndexOfValue returns.
var arr = [
"a",
[
"b",
[
"c"
],
[
"d"
],
"e"
],
"f",
[
"g"
],
"h"
]
function getIndexOfValue(haystack, needle) {
for(i in haystack) {
if(haystack[i] instanceof Array) {
result = getIndexOfValue(haystack[i], needle);
if(result) {
return result;
}
}
else if(haystack[i] == needle) {
return i;
}
}
return false;
}
var indexOfA = getIndexOfValue(arr, "a");
var indexOfB = getIndexOfValue(arr, "b");
var indexOfC = getIndexOfValue(arr, "c");
var indexOfD = getIndexOfValue(arr, "d");
var indexOfE = getIndexOfValue(arr, "e");
var indexOfF = getIndexOfValue(arr, "f");
var indexOfG = getIndexOfValue(arr, "g");
var indexOfH = getIndexOfValue(arr, "h");
console.log(indexOfA); //0
console.log(indexOfB); //0
console.log(indexOfC); //0
console.log(indexOfD); //0
console.log(indexOfE); //3
console.log(indexOfF); //2
console.log(indexOfG); //0
console.log(indexOfH); //4
It might still contain bugs, I created this quickly in a few minutes.
For getting the full path, you might use an iterative and recursive approach for the nested array.
The result is an array with all indices.
function findPath(array, value) {
var path = [];
array.some(function iter(p) {
return function (a, i) {
if (a === value) {
path = p.concat(i);
return true;
}
if (Array.isArray(a)) {
return a.some(iter(p.concat(i)));
};
};
}([]));
return path;
}
var array = ['a', ['b', ['c'], ['d'], 'e'], 'f', ['g'], 'h'];
console.log(findPath(array, 'a'));
console.log(findPath(array, 'b'));
console.log(findPath(array, 'c'));
console.log(findPath(array, 'd'));
console.log(findPath(array, 'e'));
console.log(findPath(array, 'f'));
console.log(findPath(array, 'g'));
console.log(findPath(array, 'h'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

there is an string array A , and an string array B . I want to delete elements in A which are not in B

I think i messed somewhere, Here is my code.
var flag;
for (i = 0; i < A.length; i++)
{
flag = 0;
for (j = 0; j < B.length; j++)
{
if (A[i].indexOf(B[j]) != -1)
{
flag = 1;
}
}
if (flag == 0)
{
A.splice(i, 1);
}
}
It gives output not as per my need
Someone please Help me out
I would do the job like this;
//returns intersection of multiple arrays
Array.prototype.intersect = function(...a) {
return [this,...a].reduce((p,c) => p.filter(e => c.includes(e)));
};
var a = [0,1,2,3,4,5],
b = [4,5,6,7,8,9];
a = a.intersect(b);
console.log(a);
You could use a function which generates first an object with all characters as properties and take it as hashtable for the filtering of array1.
function deleteSome(array1, array2) {
var o = Object.create(null);
array2.forEach(function (a) {
o[a] = true;
});
return array1.filter(function (a) {
return this[a];
}, o);
}
var a = 'abcdefgh'.split(''),
b = 'banana'.split('');
console.log(deleteSome(a,b));
Technically, array "a" should have only elements which are present in array "b".
var a = [1,2,3,4];
var b = [4,5,6];
var new_a = [];
a.map(function(v,i,a){
if(b.indexOf(v) !== -1){
new_a.push(v);
}
});
console.log(new_a); //[4]
By this way i can filter as many arrays as you want.
var a = ['A', 'A', 'R', 'S', 'M', 'D', 'E']
var b = ['C', 'X', 'D', 'F']
//you can add as many arrays as you want
/*var c = ['O', 'P', 'D', 'Q']
var d = ['R', 'D', 'D', 'Z']*/
var arrays = [a,b, /*c , d */];
var result = arrays.shift().filter(function(v) {
return arrays.every(function(a) {
return a.indexOf(v) !== -1;
});
});
console.log(JSON.stringify(result));

Function to return distinct values in a 2D array

I have the following 2D array
var items = [['al','bv','sd'],
['al','cc','ab'],
['cv','vv','sw'],
['al','bv','sd']
];
I need a function which will return me a similar array but with distinct values. For example, in the above array, ['al','bv','sd'] happens twice.
I would like the function to return me:
var items = [['al','bv','sd'],
['al','cc','ab'],
['cv','vv','sw']
];
Quick and dirty solution, assuming the data is small.
On each iteration, convert the row to a string. Use a dictionary to store the string with a value of True, if it is not already in the map. Also, add it to your output array. If it is already in the dictionary, go to the next item.
Example:
var d = {};
var out = [];
for( var i = 0; i < items.length; i++ ) {
var item = items[i];
var rep = item.toString();
if (!d[rep]) {
d[rep] = true;
out.push(item);
}
}
// out has the result
You have to loop two (or three times):
Loop through all "rows", from beginning to the end
Loop again, through all "rows", from beginning to the end
If the lists are equal, ignore it
Otherwise,
Loop through all "columns":
If the values are not equal, jump to the parent loop.
After the loop, remove the element using the .splice method.
Demo: http://jsfiddle.net/EuEHc/
Code:
for (var i=0; i<items.length; i++) {
var listI = items[i];
loopJ: for (var j=0; j<items.length; j++) {
var listJ = items[j];
if (listI === listJ) continue; //Ignore itself
for (var k=listJ.length; k>=0; k--) {
if (listJ[k] !== listI[k]) continue loopJ;
}
// At this point, their values are equal.
items.splice(j, 1);
}
}
A simple sort and filter, function would do the trick.
var items = [
['al', 'bv', 'sd'],
['al', 'cc', 'ab'],
['cv', 'vv', 'sw'],
['al', 'bv', 'sd']
];
var temp = ''
var unique = items.sort().filter(r => {
if (r.join("") !== temp) {
temp = r.join("")
return true
}
})
console.log(unique);
An unconventional but easier to code version
var items = [['al','bv','sd'],
['al','cc','ab'],
['cv','vv','sw'],
['al','bv','sd']
];
var temp = {};
for ( var i in items ) {
var serialized = JSON.stringify(items[i]);
if ( temp[serialized] ) {
items.splice( i, 1 );
continue;
}
temp[serialized] = true;
}
Try it here! http://jsfiddle.net/y3ccJ/1/
More conventional option:
var items = [['al','bv','sd'],
['al','cc','ab'],
['cv','vv','sw'],
['al','bv','sd']
];
var results = [];
loop: for ( var i in items ) {
compare: for ( var j in results ) {
for ( var k in items[i] ) {
if ( items[i][k] !== results[j][k] ) {
break compare;
}
}
continue loop;
}
results.push( items[i] );
}
http://jsfiddle.net/xhrd6/
If you can use lodash, this is good solution (note that based on your platform, the "require" keyword can differ, this is how to use it in Node.js):
var _ = require('lodash');
var objects = [['a', 'b', 'c'],['a'],['b', 'a', 'c']];
objects.forEach(innerArr => {
innerArr.sort();
});
console.log(_.uniqWith(objects, _.isEqual));
This would be output
[ [ 'a', 'b', 'c' ], [ 'a' ] ]
If order of elements in array matter to you, i.e. this array [ 'a', 'b', 'c' ] is considered different than this one ['b', 'a', 'c'], all you need is to delete the "sort" part :
var _ = require('lodash');
var objects = [['a', 'b', 'c'],['a'],['b', 'a', 'c'], ['a','b','c']];
console.log(_.uniqWith(objects, _.isEqual));
This would be output :
[ [ 'a', 'b', 'c' ], [ 'a' ], [ 'b', 'a', 'c' ] ]
You can do something like this :
var result = [];
result.push(items[0]);
for (i = 1; i < items.length; i++){
var ok;
for (j = 0; j < i; j++){
if (result[j].length != items[i].lenght) continue;
ok = false;
for (k = 0; k < items[i].length; k++) if (items[i][k] != result[j][k]) ok = true;
if (ok == false) break;
}
if (ok) result.push(items[i]);
}
return result;
function arrays_equal(a,b) { return !!a && !!b && !(a<b || b<a); }
Array.prototype.unique = function() {
var a = [];
for (var i = 0, l = this.length; i<l; i++) {
for (var j = i + 1; j < l; j++) if (arrays_equal(this[i], this[j])) j = ++i;
a.push(this[i]);
}
return a;
};
var ret = items.unique();
The demo.
Since this sounds like some sort of school assignment I will provide ideas not code. You should think about how a human looks through that 2D array and determines whether or not one of the arrays is unique or not. One has to look at each other row, for each row to determine if it is unique. Sounds like nested for loop to me ....

Retrieving Keys from JSON Array key-value pair dynamically - Javascript

I have a question that would like to seek your expertise on.
This is a JSON array that I have:
[{"A":20,"B":32,"C":27,"D":30,"E":40}]
What I would like to do is to retrieve the keys (A, B, C, D, E) from the JSON array instead of the values. I am able to retrieve the values but not the keys.
I am using this to retrieve the values dynamically:
function calculateSum(jsonArray) {
var result = 0;
for (var i = jsonArray.length - 1; i >= 0; --i)
{
var o = jsonArray[i];
A = o.A;
B = o.B;
C = o.C;
D = o.D;
E = o.E;
result = A + B + C + D + E;
return result;
}
return result;
}
Similarly, what should I do to retrieve the keys using JavaScript?
Are you using D3.js as your tag implies? Because in that case, you can just use d3.keys():
var data = [{"A":20,"B":32,"C":27,"D":30,"E":40}];
d3.keys(data[0]); // ["A", "B", "C", "D", "E"]
If you want the sum of all the values, you might be better off using d3.values() and d3.sum():
var data = [{"A":20,"B":32,"C":27,"D":30,"E":40}, {"F":50}];
// get total of all object totals
var total = d3.sum(data, function(d) {
// get total of a single object's values
return d3.sum(d3.values(d));
});
total; // 199
All of the current posted solutions have a problem. None of them check for object.hasOwnProperty(prop) while iterating over an object using a for...in loop. This might cause phantom keys to appear if properties are added to the prototype.
Quoting Douglas Crockford
Be aware that members that are added to the prototype of the object will be included in the enumeration. It is wise to program defensively by using the hasOwnProperty method to distinguish the true members of the object.
Adding a check for hasOwnProperty to maerics' excellent solution.
var getKeys = function (arr) {
var key, keys = [];
for (i = 0; i < arr.length; i++) {
for (key in arr[i]) {
if (arr[i].hasOwnProperty(key)) {
keys.push(key);
}
}
}
return keys;
};
Use for .. in:
var result = 0;
for (var i = jsonArray.length - 1; i >= 0; --i) {
var o = jsonArray[i];
for (var key in o) {
if (o.hasOwnProperty(key)) {
result += o[key];
}
}
// in your code, you return result here,
// which might not give the right result
// if the array has more than 1 element
}
return result;
var easy = {
a: 1,
b: 2,
c: 3
}
var keys = [], vals = []
for (var key in easy) {
keys.push(key)
vals.push(easy[key])
}
alert(keys+" - tha's how easy baby, it's gonna be")
alert(vals+" - tha's how easy baby, it's gonna be")
defensively
Including #Sahil's defensive method...
for (var key in easy) {
if (easy.hasOwnProperty(key)) {
keys.push(key)
vals.push(easy[key])
}
}
Try using the JavaScript for..in statement:
var getKeys = function(arr) {
var key, keys = [];
for (i=0; i<arr.length; i++) {
for (key in arr[i]) {
keys.push(key);
}
}
return keys;
};
var a = [{"A":20, "B":32, "C":27, "D":30, "E":40}, {"F":50}]
getKeys(a); // => ["A", "B", "C", "D", "E", "F"]
I think this is the simplest.
var a = [{"A":20,"B":32,"C":27,"D":30,"E":40}];
Object.keys( a[0] );
Result :
["A", "B", "C", "D", "E"]
A for-in-loop does the trick. On one object it looks like this:
var o = {
a: 5,
b: 3
};
var num = 0;
for (var key in o) {
num += o[key];
}
alert(num);
Try this. It is simple:
var a = [{"A":20,"B":32,"C":27,"D":30,"E":40}];
for(var i in a){
for(var j in a[i]){
console.log(j); // shows key
console.log(a[i][j]); // shows value
}
}
I think this should be parsed recursively like below
var getKeys = function(previousKeys,obj){
var currentKeys = Object.keys(obj);
previousKeys = previousKeys.concat(currentKeys);
for(var i=0;i<currentKeys.length;i++){
var innerObj = obj[currentKeys[i]];
if(innerObj!==null && typeof innerObj === 'object' && !Array.isArray(innerObj)){
return this.getKeys(previousKeys,innerObj);
}
}
return previousKeys;
}
usage: getKeys([],{"a":"1",n:{c:"3",e:{ f:4,g:[1,2,3]}}})
Result:
["a", "n", "c", "e", "f", "g"]
var _ = require('underscore');
var obj = [{"A":20,"B":32,"C":27,"D":30,"E":40},{"F":50}, {"G":60,"H":70},{"I":80}];
var keys = [], values = [];
_.each(obj, function(d) {
keys.push(_.keys(d));
values.push(_.values(d));
});
// Keys -> [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' ]
console.log('Keys -> ', _.flatten(keys ));
// Values -> [ 20, 32, 27, 30, 40, 50, 60, 70, 80 ]
console.log('Values -> ', _.flatten(values));
stop reinventing the wheel !
Object.keys()
MDN

Categories

Resources