Sorting Four Dimensional array - Javascript - javascript

I want to sort four dimensional array based on 1 column by using following method,
var main_arr = [
[]
];
var hdnFromValues = [11,16,12,17,14,18,15];
var hdnToValues = [12,17,13,18,15,19,16];
var hdnSPIDs = [11,12,13,14,0,0,0];
var hdnFlag = [D,E,E,D,A,A,A];
for (var j = 0; j < hdnFromValues.length; j++) {
var temp_arr = [];
var HdnToValue;
temp_arr.push(hdnFromValues[j]);
temp_arr.push(hdnToValues[j]);
temp_arr.push(hdnSPIDs[j]);
temp_arr.push(hdnFlag[j]);
main_arr.push(temp_arr);
temp_arr = null;
}
main_arr.sort(sort_by_col);
hdnFrom = "";
hdnTo = "";
spid = "";
flags = "";
for (var i = 1; i < main_arr.length; i++) {
hdnFrom = hdnFrom.concat(main_arr[i][0], ",");
hdnTo = hdnTo.concat(main_arr[i][1], ",");
spid = spid.concat(main_arr[i][2], ",");
flags = flags.concat(main_arr[i][3], ",");
}
hdnFrom = hdnFrom.substring(0, hdnFrom.length - 1);
hdnTo = hdnTo.substring(0, hdnTo.length - 1);
spid = spid.substring(0, spid.length - 1);
flags = flags.substring(0, flags.length - 1);
alert(hdnFrom);
alert(hdnTo);
alert(spid);
alert(flags);
function sort_by_col(a, b) {
return a[0] - b[0];
}
Sometimes, 3 & 4th column not arranging correctly as per 1st column.
Will someone help me?
JSFilddle

Change,
function sort_by_col(a, b) {
return a[0] - b[0];
}
to
function sort_by_col(a, b) {
return a[0] - b[0] || a[1] - b[1];
}

Related

how to get common substring in two string to maintain order?

I am trying to do one problem of hackerrank but I am not able to solve that problem
Can someone please help me with wrong logic implementation done by me?
problem
Print the length of the longest string, such that is a child of both s1 and s2.
Sample Input
HARRY
SALLY
Sample Output
2
Explanation
The longest string that can be formed by deleting zero or more characters from HARRY and SALLY is AY, whose length is 2.
Sample Input 1
AA
BB
Sample Output 1
0
Explanation 1
AA and BB have no characters in common and hence the output is 0
Sample Input 2
SHINCHAN
NOHARAAA
Sample Output 2
3
Explanation 2
The longest string that can be formed between SHINCHAN and NOHARAAA while maintaining the order is NHA.
I have written some logic which is as follows:
function commonChild(s1, s2) {
var arr = s2.split(),
currenString = '',
maxLength = 0,
index = -1;
console.log(arr);
for (var i = 0; i < s1.length; i++) {
var char = s1.charAt(i),
charIndex = arr.indexOf(char);
console.log(char)
if (index < charIndex) {
index = charIndex;
currenString +=char;
}
maxLength= Math.max(maxLength,currenString.length)
}
return maxLength;
}
commonChild('ABCDEF', 'FBDAMN');
console.log(commonChild('ABCDEF', 'FBDAMN'));
pardon me. this is an unoptimized solution.
function maxCommon(a, b, offset) {
offset = offset || 0;
if (a === b) {
return [[a, b]];
}
var possibleSolns = [];
for (var i = 0 + offset; i < a.length; i++) {
for (var j = 0 + offset; j < b.length; j++) {
if (a.charAt(i) === b.charAt(j)) {
possibleSolns.push([
a.substring(0, offset) + a.substring(i),
b.substring(0, offset) +b.substring(j)
]);
break;
}
}
}
var results = [];
possibleSolns.forEach(function(soln) {
var s = maxCommon(soln[0], soln[1], offset+1);
if (s.length === 0) {
s = [[soln[0].substring(0, offset +1), soln[1].substring(0, offset +1)]];
}
results = results.concat(s);
});
return results;
}
var maxLen = -1;
var soln = null;
maxCommon("ABCDEF", "FBDAMN").map(function(_) {
return _[0];
}).forEach(function(_) {
if (_.length > maxLen) {
soln = _;
maxLen = _.length;
}
});
console.log(soln);
I kept most of your logic in the answer:
function commonChild(s1, s2) {
var // Sets strings to arrays
arrayString1 = s1.split(""),
arrayString2 = s2.split(""),
collectedChars = "",
maxLength = 0,
max = arrayString1.length;
for (var i = 0; i < max; i++) {
var
char = arrayString1[i],
count = arrayString2.indexOf(char);
// check if char is in second string and not in collected
if (count != -1 && collectedChars.indexOf(char) == -1) {
collectedChars += char;
maxLength++;
}
}
return maxLength;
}
// expected output 4
console.log(commonChild(
'ABCDEF',
'FBDAMN'
));
// expected output 1
console.log(commonChild(
'AA',
'FBDAMN'
));
Using lodash and spread operation you can do it in this way.
const test = (first, second) => {
const stringArray1 = [...first];
const stringArray2 = [...second];
return _.intersection(stringArray1, stringArray2).length;
}
console.log(test('ABCDEF', 'FBDAMN'));
You can solve it using lcs least common subsequence
function LCS(s1,s2,x,y){
var result = 0;
if(x==0 || y==0){
result = 0
}else if(s1[x-1] == s2[y-1]){
result = 1+ LCS(s1,s2,x-1,y-1)
} else if(s1[x-1] != s2[y-1]){
result = Math.max(LCS(s1,s2,x-1,y), LCS(s1,s2,x,y-1))
}
return result;
}
// Complete the commonChild function below.
function commonChild(s1, s2) {
return LCS(s1,s2,s1.length,s2.length);
}
Based on your code before the edit.
One little change is to change var arr = s2.split() to split('').
The main change in the logic is that I added a loop to run over the string each time from another character (first loop from the first, second from the second etc).
function commonChild(s1, s2) {
var arr = s2.split(''),
currenString = '',
maxLength = 0,
index = -1,
j = -1;
for (var ii = 0; ii < s1.length; ii++) {
index = -1;
currenString = '';
for (var i = ii; i < s1.length; i++) {
var char = s1.charAt(i),
j = arr.indexOf(char);
if (index < j) {
index = j;
currenString += char;
}
maxLength = Math.max(maxLength, currenString.length)
}
}
return maxLength;
}
console.log(commonChild('ABCDEF', 'FBDAMN'));

How to generate an addition equation for a number using only required set of numbers?

I want to generate an addition equation for a random number which is look likes
5+10+2 from a set of numbers i.e [1,2,5,10,50].
var randomNumber = Math.floor(Math.random() * (10 - 1 + 1)) + 1;
var setOfNums = [1,2,5,10,50];
var additionEquation; //ex: for randomNumber = 28; additionEquation = 10+10+5+2+1;
And the maximum number of elements in equation is 5.Is it possible in java script?Thanks in advance.
You may have multiple solutions. A dynamical programming approach could efficiently solve this;
function getCombos(a,t){
var h = {},
len = a.length,
n = 0;
for (var i = 0; i < len; i++){
n = a[i];
h[n] ? h[n].push([n]) : h[n] = [[n]];
for(var j = a[0]; j <= t-n; j++){
h[j] && (h[j+n] = h[j+n] ? h[j+n].concat(h[j].map(s => s.concat(n)))
: h[j].map(s => s.concat(n)));
}
}
return h[t] || [];
}
var arr = [1,2,5,10,50],
target = 28,
result = [];
console.time("combos");
result = getCombos(arr,target);
console.timeEnd("combos");
console.log(`${result.length} solutions found`);
console.log(JSON.stringify(result));
Then you may choose the shortest one among the results set. However calculating according to a maxlen will of couse save us from calculating excess results just to be filtered out later. So the following code only works up until the maxlen is achieved.
function getCombos(a,t,l){
var h = {},
len = a.length,
n = 0;
for (var i = 0; i < len; i++){
n = a[i];
h[n] ? h[n].push([n]) : h[n] = [[n]];
for(var j = a[0]; j <= t-n; j++){
h[j] && (h[j+n] = h[j+n] ? h[j+n].concat(h[j].reduce((r,s) => s.length < l ? (r.push(s.concat(n)),r) : r, []))
: h[j].reduce((r,s) => s.length < l ? (r.push(s.concat(n)),r) : r, []));
}
}
return h[t] || [];
}
var arr = [1,2,5,10,50],
target = 28,
maxlen = 5,
result = [];
console.time("combos");
result = getCombos(arr,target,maxlen);
console.timeEnd("combos");
console.log(result.length)
console.log(JSON.stringify(result));
I believe performance wise this can not be beaten easily. It takes only .190ms to get to the result [[1,2,5,10,10]].
This problem can be solved with a recursive combinations of all possible sums until we reach the target.
One solution contains maximum 5 as a length where 5 is the length of the setOfNums array.
var randomNumber = Math.floor(Math.random() * 30) + 1;
console.log(randomNumber);
var setOfNums = [1,2,5,10,50];
setOfNums=setOfNums.sort(function(a,b){
return b-a;
});
subset_sum(setOfNums,randomNumber);
function subset_sum(numbers, target, partial){
partial = partial || [];
s = partial.reduce(function(contor,elem){
return contor+elem;
},0);
if(s == target){
partial=partial.sort(function(a,b){
return a-b;
});
console.log("sum"+JSON.stringify(partial)+"="+ target);
}
if(s >= target)
return;
if(partial.length>numbers.length)
return;
numbers.forEach(function(number,index){
n = numbers[index];
subset_sum(numbers, target, partial.concat(n));
});
}

How can I split the below string into a 2dimensional-array:

How can I split the below string into a 2dimensional-array:
Customer::Europe|UK|Scotland|Product::Drinks|Water|
array:
[Customer][Europe]
[Customer][UK]
[Customer][Scotland]
[Product][Drinks]
[Product][Water]
Not sure how to create the array. Haven't coded in years, so be kind
hArray= [];
vArray= [];
var i = j = 0;
var count = hierarchy.search(/[:|]+/);
write(hierarchy);
while (count > 0) {
if (hierarchy.indexOf(":") < hierarchy.indexOf("|") || (hierarchy.indexOf(":") > 0 && hierarchy.indexOf("|") == -1) ) {
hArray[j] = hierarchy.substr(0,hierarchy.indexOf(":"));
hierarchy = hierarchy.slice(hierarchy.indexOf(":")+2);
count = hierarchy.search(/[:|]+/);
j++;
} else
if (hierarchy.indexOf("|") < hierarchy.indexOf(":") {
vArray[i] = hierarchy.substr(0,count);
hierarchy = hierarchy.slice(count+1);
count = hierarchy.search(/[:|]+/);
i++;
}
if (count == -1) break;
//create multiArray ?
}
var source = "Customer::Europe|UK|Scotland|Product::Drinks|Water|";
var parts = source.split(/(\w+::)/);
var result = [];
for (var i = 1; i < parts.length; i += 2) {
var key = parts[i].replace("::", "");
var values = parts[i + 1].split("|");
for (var j = 0; j < values.length - 1; ++j) {
var line = new Array(2);
line[0] = key;
line[1] = values[j];
result.push(line);
}
}
console.log(result);
You can use Array.reduce like this. First, we split on | that is behind any owrd followed by ::. Then we reduce it, by using an array as memo and push an array into the memo, which we finally return.
var arr = input.split(/\|(?=\w+::)/).reduce(function(arr, str){
var array = str.split('::');
return arr.push(str.split('::')[1].split('|').filter(String).map(function(s){
return [array[0], s]
})), arr;
}, []);

Find out if array contains arithmetic progression in javascript

I have an array:
var myarray = [1,2,3,4,7,9,12,13,14]
I need to group values like so:
var array_1 = 1,2,3,4
var array_2 = 7
var array_3 = 8
var array_4 = 12,13,14
I need to find a sequences with an arithmetic progression and seperate from other values.
Any ideas?
Check out this solution
function explode(myarray)
{
var multi = [];
var i = j = 0;
for ( key in myarray )
{
if((myarray[key-1]) != (myarray[key]-1))
{
i++;
j=0;
}
if(j==0)
multi[i] = [];
multi[i][j] = myarray[key];
j++;
}
return multi;
}
It returns a multidimentionnal array that you can use in your example like this
var myarray = [1,2,3,4,7,9,12,13,14];
var multi_array = explode(myarray);
var array_1 = multi_array[0];
var array_2 = multi_array[1];
var array_3 = multi_array[2];
var array_4 = multi_array[3];
New update :
You can also remove the j index and use .push to add new elements to your array
function explode(myarray)
{
var multi = [];
var i = 0;
for ( key in myarray )
{
if((myarray[key-1]) != (myarray[key]-1))
i++;
if(!multi[i])
multi[i] = [];
multi[i].push(myarray[key]);
}
return multi;
}
The following seems to work, but displays a slightly different output than the one you expect.
In your example, I think 7 and 9 should be grouped (any sequence of two items is an arithmetic
progression after all). Or if they are not grouped, then 12 should not be grouped with 13 and
14 either, since 12-9 != 13-12
function split(arr) {
if (arr.length < 2) {
return;
}
var delta = undefined;
var start = 0;
for (var idx = 1; idx < arr.length; idx++) {
if (delta === undefined) {
delta = arr[idx] - arr[idx - 1];
}
if (arr[idx] - arr[idx - 1] != delta) {
alert("subarray " + arr.slice(start, idx));
start = idx;
delta = undefined;
}
}
alert("subarray from" + arr.slice(start, arr.length));
}
split([1,2,3,4,7,9,12,13,14]);
arrays = Array();
var c = 0;
array[c][] = myarray[0]);
for (var i = 1; i<myarray.length; i++) {
if (myarray[i-1] +1 != myarray[i])
c++;
array[c][] = push(myarray[i]);
}
not sure the array syntax (might mix up languages here) is correct or whether I understand your problem fully.

Using Javascript find array values in another array and in order

Here is one to get your brain going! I've not had any luck with it.
[1,2,1,1,2,1,1,1,2,2]
[1,2,1,1,2,1]
I would like to use the second array to find the values in the first, but they must be in the same order.
Once for I would like it to return the next key up from the last key in the second array.
So in this example it would use the first six digits in the first array and then return 6 as the key after the final one in the second array.
var a2 = [1,2,1,1,2,1,1,1,2,2]
var a1 = [1,2,1,1,0,1]
function find(arr1, arr2) {
var len = 1
var result = 0;
var s2 = arr2.toString();
for (len=1;len <= a1.length; len++)
{
var aa1 = arr1.slice(0, len)
var s1 = aa1.toString();
if(s2.indexOf(s1)>=0){
result = aa1.length;
}
else {
break;
}
}
return result;
}
alert(find(a1, a2));
var find = function(haystack, needle) {
var doesMatch = function(offset) {
for (var i = 0; i < needle.length; i++) {
if (haystack[i+offset] !== needle[i]) {
return false;
}
}
return true;
};
for (var j=0; j < haystack.length - needle.length; j++) {
if (doesMatch(j)) {
return j;
}
}
return -1;
};
This is quick, this is dirty, and this is correct only if your data doesn't include any comma.
var needle = [1,2,1,1,2,1];
var haystack = [1,2,1,1,2,1,1,1,2,2];
if ( needle.length <= 0 ) return 0;
var fromStr = ','+haystack.toString()+','
var findStr = ','+needle.toString()+','
// Find ',1,2,1,1,2,1,' in ',1,2,1,1,2,1,1,1,2,2,'
var pos = fromStr.indexOf(findStr);
// Count the end position requested
return pos >= 0 ? fromStr.slice(0,pos+1).match(/,/g).length + needle.length - 1 : -1;
Note: The comma at head and tail is to make sure [22,12] doesn't match [2,1].

Categories

Resources