Converting a JavaScript snippet to C# - javascript

I am trying to convert the following JS snippet into C#, but am having a hard time understanding the implicit types being used.
initHuffman = function(size) {
this.huffmanTree = [];
var code = 0;
for (var d = 0; d < (size * 2); d++) {
var count = this.getBits(size);
for (var v = 0; v < count; v++) {
var node = this.huffmanTree;
for (var d1 = d; d1 !== 0; d1--) {
var c = (code >> d1) & 1;
if (!node[c]) node[c] = [];
node = node[c];
if (isNumber(node)) return;
}
node[code & 1] = this.getBits(size);
code++;
}
code <<= 1;
}
}
This is a function to decode a string of bits into a Huffman tree. The issue I am having is with the node object. node is of type any[], and references huffmanTree which is of type any[].
The first confusing part is if (!node[c]) node[c] = []; It seems the code is checking if an index exists in node, and if it doesn't, add an empty array?
The second confusing part is node[code & 1] = this.getBits(size); The getBits() function simply reads a few bits, in this case 4, and returns them as an int. So, it seems node can be indexed with ints and with arrays?
How would I accomplish this in C#? What collection or array type could do this?
Running this through the debugger in FireFox gives the following result:
0: 0
1: [...]
0: 1
1: [...]
0: 2
1: [...]
0: 3
1: 4
I am clearly not understanding what is happening here. Any help would be appreciated.

Related

Reverse a string using two-pointer method in JS

I am trying to reverse a string. I am aware of .reverse function and other methods in Js to do so, but i wanted to do it this two-pointer method.
The problem is the string is not getting updated. Is there anything i am not aware of strings. Whats wrong here ?
function reverseString(s) {
let lengthOfStr = 0;
if ((s.length - 1) % 2 == 0) {
lengthOfStr = (s.length - 1) / 2
} else {
lengthOfStr = ((s.length - 1) / 2) + 1;
}
let strLengthLast = s.length - 1;
for (let i = 0; i <= lengthOfStr; i++) {
let pt1 = s[i];
let pt2 = s[strLengthLast];
s[i] = pt2;
s[strLengthLast] = pt1;
console.log('----', s[i], s[strLengthLast]);
strLengthLast--;
}
return s;
}
console.log(reverseString('hello'));
Unlike in C, strings in JavaScript are immutable, so you can't update them by indexing into them. Example:
let s = 'abc';
s[1] = 'd';
console.log(s); // prints abc, not adc
You'd need to do something more long-winded in place of s[i] = pt2;, like s = s.substring(0, i) + pt2 + s.substring(i + 1);, and similarly for s[strLengthLast] = pt1; (or combine them into one expression with 3 calls to substring).
I'm not sure why it doesnt update the string, but if you handle the replacement as an array/list it works as follows:
function reverseString(s) {
let lengthOfStr = 0;
sSplit = s.split("");
if ((s.length - 1) % 2 === 0) {
lengthOfStr = (s.length - 1) / 2
}
else {
lengthOfStr = ((s.length - 1) / 2) + 1;
}
let strLengthLast = s.length - 1;
for (let i = 0; i <= lengthOfStr; i++) {
let pt1 = sSplit[i];
let pt2 = sSplit[strLengthLast];
sSplit[i] = pt2;
sSplit[strLengthLast] = pt1;
console.log('----', sSplit[i], sSplit[strLengthLast],sSplit);
strLengthLast--;
}
return sSplit.join("");
}
console.log(reverseString('Hello'));
returns: Hello => olleH
As covered in comment, answers and documentation, strings are immutable in JavaScript.
The ability to apparently assign a property value to a primitive string value results from early JavaScript engine design that temporarily created a String object from primitive strings when calling a String.prototype method on the primitive. While assigning a property to the temporary object didn't error, it was useless since the object was discarded between calling the String method and resuming execution of user code.
The good news is that this has been fixed. Putting
"use strict";
at the beginning of a JavaScript file or function body causes the compiler to generate a syntax error that primitive string "properties" are read-only.
There are many ways of writing a function to reverse strings without calling String.prototype.reverse. Here's another example
function strReverse(str) {
"use strict";
let rev = [];
for( let i = str.length; i--;) {
rev.push(str[i]);
}
return rev.join('');
}
console.log( strReverse("Yellow") );
console.log( strReverse("").length);
I tried that way, hopefully might be helpful for someone.
const input = 'hello'; /*input data*/
const inputArray = [...input]; /*convert input data to char array*/
function reverseString(inputArray) {
let i = 0;
let j = inputArray.length -1 ;
while(i < j ) {
const temp = inputArray[i];
inputArray[i] = inputArray[j];
inputArray[j] = temp;
i++;
j--;
}
};
reverseString(inputArray);
console.log(inputArray)
const finalResult = inputArray.join("");
console.log(finalResult);
Thanks.

Iterate two string arrays simultaneously using javascript

I am new to javascript. Now, I want to make comparison of two website pair by iterating two string array as a pair the same time. These two string array's length are the same. I have searched for sites but didn't find the way to do in javascript. For example, in python, people can do this by using zip(), referencing from
How to merge lists into a list of tuples?.
However, in javascript, I try to something similar to that, but it will iterate over the second list every time it iterate over the element of first list, which is not want I wanted.
codes not what I expected
var FistList=['https://test1-1/travel','https://test1-1/cook','https://test1-1/eat'];
var SecondList=['https://test1-2/travel','https://test1-2/cook','https://test1-2/eat'];
FirstList.forEach(firstListItem => {
SecondList.forEach(secondListItem => {
//do comparison for these two websites....
});
});
What I expect is to do comparison pair by pair, which is =>
first loop: do comparison of 'https://test1-1/travel' and 'https://test1-2/travel'
second loop: do comparison of 'https://test1-1/cook' and 'https://test1-2/cook'
third loop: do comparison of 'https://test1-1/eat' and 'https://test1-2/eat'
I searched for a whole day but cannot find the way to do in javascript. Please advise. Thanks in advance!
If all you want is to compare values in same position of each array just use the index argument of forEach to reference array element in other array
var FirstList=['https://test1-1/travel','https://test1-1/cook','https://test1-1/eat'];
var SecondList=['https://test1-2/travel','https://test1-1/cook','https://test1-1/eat'];
FirstList.forEach((str, i) => console.log(str === SecondList[i]))
I think a very similar question was already answered here: How to compare arrays in JavaScript?
Accepted answer (https://stackoverflow.com/a/14853974/1842205) describes in depth how you could achieve such a goal.
JavaScript lacks of such a feature like mentioned zip() method from Python. But we have something like prototyping in JS :). And you can create 2D array like below:
function createArray(length) {
var arr = new Array(length || 0),
i = length;
if (arguments.length > 1) {
var args = Array.prototype.slice.call(arguments, 1);
while(i--) arr[length-1 - i] = createArray.apply(this, args);
}
return arr;
}
Array.prototype.zip = function (secondArr) {
let result = createArray(secondArr.length, 2);
for (let i = 0; i < this.length; i++) {
result[i][0] = this[i];
result[i][1] = secondArr[i];
}
return result;
};
// usage
var FistList=['https://test1-1/travel','https://test1-1/cook','https://test1-1/eat'];
var SecondList=['https://test1-2/travel','https://test1-2/cook','https://test1-2/eat'];
console.log(JSON.stringify(FistList.zip(SecondList)));
I like the OP's idea of making a more functional solution using zip, which can be home-rolled or reused from loadash or underscore.
const firstArray=['https://test1-1/travel','https://test1-1/cook','https://test1-1/eat'];
const secondArray=['https://test1-2/travel','https://test1-2/cook','https://test1-2/eat'];
const zipped = _.zip(firstArray, secondArray)
const compared = zipped.map(([first, second]) => first === second)
console.log(compared)
// reduce the pairwise comparison to a single bool with every()
// depends on requirements, but probably true iff every comparison is true
const arraysMatch = compared.every(e => e)
console.log(arraysMatch)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>
Note that more functional solutions often involve the creation of some intermediate arrays (aka garbage) which is fine for small inputs.
I think the purpose of a forEach loop is to iterate over 1 list only. I would consider using a generic for loop to serve this purpose.
EDIT: I edited the code, and added a string prototype function to calculate the Levenstein distance between 2 strings. It's not rigid to detect for an edit in the exact spot your strings are changed in the examples. But I expect the examples are probably not totally reflective of your real data anyway, so instead of giving you some questionable regex, I'm giving you Levenstein and hope you understand it doesn't care where the difference is, it just cares how much has changed. In the example I only allow 1 character or less of difference: if (diff <= 1) {
//Define a string function for Levenstein Edit Distance
//call it "distancefrom" for clarity
String.prototype.distancefrom = function(string) {
var a = this, b = string + "", m = [], i, j, min = Math.min;
if (!(a && b)) return (b || a).length;
for (i = 0; i <= b.length; m[i] = [i++]);
for (j = 0; j <= a.length; m[0][j] = j++);
for (i = 1; i <= b.length; i++) {
for (j = 1; j <= a.length; j++) {
m[i][j] = b.charAt(i - 1) == a.charAt(j - 1)
? m[i - 1][j - 1]
: m[i][j] = min(
m[i - 1][j - 1] + 1,
min(m[i][j - 1] + 1, m[i - 1 ][j] + 1))
}
}
return m[b.length][a.length];
}
//Your Code
var FirstList=['https://test1-1/travel','https://test1-1/cook','https://test1-1/eat', 'https://waffles.domain/syrup', 'http://pancakes.webpresence/butter'];
var SecondList=['https://test1-2/travel','https://test1-2/cook','https://test1-2/eat', 'https://waffles.domain/syrups', 'https://pancakes.webpresence/buttery'];
for (let i=0; i < FirstList.length; i++) {
let diff = FirstList[i].distancefrom(SecondList[i]);
console.log('"'+FirstList[i]+'" is different than "'+SecondList[i]+'" by '+diff+' characters');
if (diff <= 1) {
console.log('Since its less than 1 character of difference, it would technically Pass our test.');
} else {
console.log('Since its more than 1 character of difference, it would Fail our test!');
}
console.log('-----------------');
}
References:
Levenstin Gist by scottgelin on GitHub

How to load a multidimensional array using for loop in JS?

[just joined. first post \o/]
I'm working on a 'battleblocks' project idea of mine to help learn JS, where I have a 10x10 css grid of dynamically created divs. They are identifiable from numbers 1 to 100, reading left to right (row 1 has 1,2,3..10, row 2 has 11,12..20 etc). I need to be able to have a nested array of columns that house 10x arrays (columnArray[0] contains 1,11,21..91 - columnArray[1] contains 2,12,22..92 etc). And the same for rows - a row array that has 10x row arrays (rowArray[0] contains 1,2,3..10 - rowArray[1] contains 11,12,13..20 etc).
Ive declared column array globally, but as it stands whatever ive done so far causes a 'aw, snap! something went wrong while displaying this webpage.' error.
loadColsArray();
// load column arrays
function loadColsArray() {
let rowsAr = [];
let count = 0;
for (let c = 1; c <= 10; c++) {
for (let r = 0; r <= 100; r + 10) {
rowsAr[count] = c + r;
count++;
}
columnArray[c - 1] = rowsAr;
count = 0;
rowsAr = [];
}
console.log(columnArray);
}
Any help appreciated.
ps: added code as a snippet, because 'code sample' option broke up my pasted code.
There are a few problems in your code:
The "Aw Snap" is caused by an infinite loop in your code which occurs because you never increment r. You must use r += 10 to increment it by 10.
Since you initialise r to 0, your exit condition must be r < 100, otherwise 11 iterations will occur.
You also need to define columnArray before you use it (it's not defined in the snippet).
Try this:
let columnArray = []; // ←
loadColsArray();
// load column arrays
function loadColsArray() {
let rowsAr = [];
let count = 0;
for (let c = 1; c <= 10; c++) {
for (let r = 0; r < 100; r += 10) { // ←
rowsAr[count] = c + r;
count++;
}
columnArray[c - 1] = rowsAr;
count = 0;
rowsAr = [];
}
console.log(columnArray);
}

Store values in an array after treat the values from another array [duplicate]

This question already has an answer here:
Find the highest subset of an integer array whose sums add up to a given target
(1 answer)
Closed 6 years ago.
I'm stumbling into a problem that I've to treat a given value and check if this value is bigger than my array of values, if it is, combine the output using my array.
For example.
My array always will be:
const ArrayPrimitive = [100,50,20,10];
And for example the given value in the input:
Entry: 30.00 Result: [20.00, 10.00]
Entry: 80.00 Result: [50.00, 20.00, 10.00]
Entry: 125.00 Result: throw NoteUnavailableException
Entry: -130.00 Result: throw InvalidArgumentException
Entry: NULL Result: [Empty Set]
I've started to develop but I'm stuck in the in how to deal with the rest, after check if the value is valid.
const ArrayPrimitive = [100,50,20,10];
var combination = [];
$(document).ready(function(){
$(".btn-submit").on("click",function(){
var amountOfMoney = document.getElementById('amountOfMoney').value;
for(let i=0; i=ArrayPrimitive.length;i++){
if(amountOfMoney=ArrayPrimitive[i]){
combination.push(amountOfMoney);
}
while(amountOfMoney > ArrayPrimitive[i]){
var k = amountOfMoney/ArrayPrimitive[i];
for(let j=0; j = k; j++){
combination.push(ArrayPrimitive[i]);
amountOfMoney = amountOfMoney - ArrayPrimitive[i];
}
var rest = n % ArrayPrimitive[i];
}
}
});
});
My major questions are:
Can you guys help me to solve this in the old way?
I'm about to learn ES6 and probably the .map or other function could save my life, could someone enlighten me in this point?
I hope I made myself clear.
https://jsfiddle.net/v748ha08/1/
UPDATE: Thanks #Malk for your answer but your solution just provides the right answer only when you don't have to combine multiple values of the subset.
e.g.
Entry: 200.00
Result: [100.00, 100.00]
In this case I need 2 values of 100 in my subset, and when I test this they functions throws me an error.
If you want to iterate through an array and build up an object (or anything else) along the way then Array.reduce() is the way to go.
const ArrayPrimitive = [100, 95, 20, 10]; // Assuming presorted array(descending)
function findChange(m) {
return ArrayPrimitive.reduce((mm, c) => {
if (mm.rest >= c) {
mm.change.push(c);
mm.rest -= c
}
return mm
}, {
change: [],
rest: m
});
}
function findChangeOld(m) {
var retval = {
change: [],
rest: m
},
i = ArrayPrimitive.length;
for (var x = 0; x < i; x++) {
if (retval.rest >= ArrayPrimitive[x]) {
retval.change.push(ArrayPrimitive[x])
retval.rest -= ArrayPrimitive[x];
}
}
return retval;
}
function calcChange(v) {
var c = findChangeOld(v);
if (v < 0 || isNaN(v)) {
console.log(`${v}: throw InvalidArgumentException`);
return;
}
if (c.rest > 0)
console.log(`${v}: throw NoteUnavailableException`);
else
console.log(`${v}: ${c.change}`);
}
calcChange(30);
calcChange(80);
calcChange(105);
calcChange(125);
calcChange(-130);
calcChange(null);

JavaScript - Hard copying primitive

I'm trying to copy a variable to a new one, NOT by reference, but by hard copy. In my understanding, JavaScript does a hard copy of primitive types by default. However, I get a reference copy if I do it like this:
var u = [0, 12, 34, 56];
var v = u[1];
u[1] = 85;
console.log(v); // returns 85, I want it to return 12
So I guess u[1] isn't a primitive type, after all (even though it's just a 12, which is a number, which should be primitive in my understanding). Is there a way I can make a hard copy? I've tried severeal methods I've found here. v = u[1].slice() seems to be the obvious choice, it doesn't work however, and there has to be an easier method for this than the 20 line custom functions some advise.
Thank you for your help!
EDIT: Apparently it works this way, so here's more of the code(without some unimportant parts):
var G = [[1, 2, 34, 56],[2, 345, 67, 8],[3, 4],[4, 65, 87]...]; // G contains 99 entries originally
var v;
var u;
var m = 99;
var alt;
var n = edges.length;
G[0].l = 0;
u = G[0].slice(); // now u = [1, 2, 34, 56]
u.l = G[0].l;
//... ...(some code not doing anything with v and u)
for (i = 1; i < ( u.length - 1 ) ; i++) {
alt = u.l + 1;
console.log(u[i]);
v = u[i];
u[i] = 9999999; //this is for testing if v is the ith of u or not
for( j = 0; j < m; j++) {
if(G[j][0] == v) {
if ( alt < G[j].l ){
Res[j].l = alt;
Res[j].previous = u;
}
}
}
for( j = 0; j < m; j++) {
if(G[j][0] == v) {
if ( alt < G[j].l ){
G[j].l = alt;
G[j].previous = u;
}
}
}
}
return v; //returns 9999999 instead of anythign from the original u, or G for that matter
Well these two lines are inside of a loop:
from your fiddle https://jsfiddle.net/7vjf82oa/1
//reduced to the core problem
while(/*whatever*/){
for(var i=1; i<u.length-1; ++i){
v = u[i];
u[i] = 9999999; //this is for testing if v is the ith of u or not
}
}
return v;
you overwrite the values in the first itertion and access them in any further one.
What are you trying to achieve with your code? It seems messed up in so many ways. Maybe we can help to solve the underlying problem.
Like this part:
for ( k = 0; k < m ; k++ ) {
if ( G[k].l < min ) {
mini = G[k][0];
u = G[mini].slice();
u.l = G[mini].l;
}
}
G.splice(mini, 1);
m--;
mini = 0;
mini seems to reference the index-position of something min.
The way you build G, G[k][0] would reference the index-Position inside of G, and mini = G[k][0] could be replaced as mini = k, except that since you remove Elements from G the indices are completely messed up, so that referencing u = G[mini].slice() would result in some sort of fancy shuffle.
Except for the fact that the surrounding condition can never be true. why?
G[/*any*/].l is initialized as Infinite.
u.l is initialized as 0 and counting up.
G[0].l = 0;
u = G[0].slice();
u.l = G[0].l;
//...
alt = u.l + 1;
//...
G[j].l = alt;
min is initialized as 0 and is never changed.
neither 0..99 nor Infinite can ever be lower than 0
so that G.splice(mini, 1); is just a substitute for G.shift();
so again, what are you trying to build? maybe we can help
if you want to clone an object or deep copy ,
there is a few ways to do it.
function clone(a) {
return JSON.parse(JSON.stringify(a));
}

Categories