How to store character code in a JavaScript Uint8Array? - javascript

In the function toCharArr the argument arr is an "array of characters"
{ Example: arr = ['H','e','l','l','o'] }
function toCharArr(arr) {
const res = new Uint8Array(arr.length);
for (let i=0; i < arr.length; i++)
res[i] = arr[i];
return res;
}
In the code above res array should ideally contain the characters ['H','e','l','l','o'] or the codes for these characters, but instead it contains only 5 zeros. This problem is baffling me as it seems to simple but yet so complex.
What have I done wrong here? Should I get the character code?
Any help would be great.

You also need to reference which index of the array you want to get the charcode of -
arr[i] and then get the charCodeAt index 0 arr[i].charCodeAt(0)

You can accomplish the same like this:
function toCharArr(str) {
return str.split('').map(elem => elem.charCodeAt(0));
}
const result = toCharArr('hello');
console.log(result);

Related

Algorithm to calculate maximum possible length of a String

Problem:
Given an array of strings arr. String s is a concatenation of a sub-sequence of arr which have unique characters.
Return the maximum possible length of s
Examples:
Input: arr = ["un","iq","ue"]
Output: 4
Explanation: All possible concatenations are "","un","iq","ue","uniq" and "ique".
Maximum length is 4.
Input: arr = ["cha","r","act","ers"]
Output: 6
Explanation: Possible solutions are "chaers" and "acters".
My solution:
var maxLength = function(arr) {
if(!arr || arr.length === 0) return 0;
let word = "";
arr.sort((a,b) => b.length - a.length);
let set = new Set();
const removeFromSet = (str) => {
for(let i=0; i<str.length; i++) {
set.delete(str[i]);
}
}
const isInSet = (str) => {
for(let i=0; i<str.length; i++) {
if(set.has(str[i])) {
removeFromSet(str.substring(0, i));
return true;
}
else
set.add(str[i]);
}
return false
}
for(let i=0; i<arr.length; i++) {
if(!isInSet(arr[i])) {
word += arr[i];
}
}
return word.length;
};
It fails for the input: ["ab","cd","cde","cdef","efg","fgh","abxyz"]
It should return 11, but my solution returns 9.
I know that my solution is calculating: "abxyzcdef" and it should be: "abxyzfghcde". Does anyone know what I am doing wrong?
Thanks
Hole algorithm is recursivly, starting with only the string-array. If the second parameter str is not defined than it's setted to an empty strin (only at start).
Iterate through the string-array look if there is a builded string. If so than split the new teststring in chars and look if there exists at least one char (with Array#some) that is included in the builded string. If this condition is as well true than the string would not be contain unique chars so we can continue. Otherwise this is till now a possible sollution.
Now take the array and remove all the teststrings which have been tried (included the actual tested) because testing with them isn't usefull. Call the algorithm itself recursivly with shortened string-array and the string extended with the actual teststring.
Look if the length of the acual teststring plus the return value of recursiv call is greater than maximum than actualisize it.
After iterateing through all testrings from the array return the maximum length from an allowed string.
Extended: I check at start all strings with Array.filter for words with multiple same chars so e.g. 'abba' will not be tested.
function maxLength(array, str) {
if (str === undefined) {
str = '';
array = array.filter(elem => elem.split('').every((char, key) => !(elem.slice(key+1)).includes(char)));
};
array = array.filter(elem => elem.split('').every((char, key) => !(elem.slice(key+1)).includes(char)));
let max=0;
for (let i=0; i<array.length; i++) {
let test= array[i];
if (str.length && test.split('').some(char => str.includes(char))) {
continue;
} else {
let len = test.length + maxLength(array.slice(i), str + test);
if (len>max) max=len;
}
}
return max;
}
console.log( maxLength(["un","iq","ue"]) );
console.log( maxLength(["cha","r","act","ers"]) );
console.log( maxLength(["ab","cd","cde","cdef","efg","fgh","abxyz"]) );
console.log( maxLength(["yy","bkhwmpbiisbldzknpm"]) );
I found your logical fault: You only look straight forward and if one string not match you leave this one out and testing the next and go on like this.
But if one string matches you never look if possible another would be better.
Explanation:
I will explain it a little more. These are your sorted strings for testing:
["abxyz", "cdef", "cde", "efg", "fgh", "ab", "cd"]
You tried these combinations(first the tested good string and second your actual candidate) and afterwardes result for testing:
abxyz => ok
abxyz cdef => ok
abxyz cdef cde => false
abxyz cdef efg => false
abxyz cdef fgh => false
abxyz cdef ab => false
abxyz cdef cd => false
So your max-length is 9 (choose the first and the second string). But the solution abxyz cde fgh you don't take a look on it. For this you had to look instead of cdef for the shorter cde which is in combination with fgh the solution.
This is only the explanation why this don't work but not how you can solve it ;).

Create a function which takes in a word and spells it out, by consecutively adding letters until the full word is completed

Create a function which takes in a word and spells it out, by consecutively adding letters until the full word is completed.
This is my code for the solution. I am super new to JS. Could someone tell me the problem? Thank you.
function spelling(str) {
var str1 = [...str]
var n
str1.index[n] = str.slice(0, n+1)
return str1
}
Expected output:
Test.assertSimilar(spelling("bee"), ['b', 'be', 'bee'])
Test.assertSimilar(spelling("cake"), ['c', 'ca', 'cak', 'cake'
Actual output:
TypeError: Cannot set property 'undefined' of undefined at spelling at
Object.handleError at ContextifyScript.Script.runInThisContext at
Object.exports.runInThisContext
First of all, you never initialized n.
In addition, what is str1.index? It does not exist. If you want to access a cell in an array you should use: array[i].
Moreover, after you defined n, you need to update it for every char.
What I did was to fix all of what I mentioned above, and I created an empty array, and for each char of str I'm pushing to the array a slice of str and update n (++n means to use n after increment it by 1).
function spelling(str) {
var str1 = [];
let n = 0;
for (c in str)
str1.push(str.slice(0, ++n));
return str1;
}
console.log(spelling('bee'));
function spelling(str) {
return str.split('').map((el,i)=>str.slice(0,i+1));
}
Map can take a second parameter which is the index of the array that map is being called on.
You can use substring to achieve this.
The substring() method extracts the characters from a string, between
two specified indices, and returns the new sub string.
function spelling(str) {
let result = [];
for (let i = 1; i <= str.length; i++) {
result.push(str.substring(0, i));
}
return result;
}
console.log(spelling('bee'));
/**
* spelling("hello") // Returns ["h", "he", "hel", "hell", "hello"]
*/
function spelling(str) {
var arr = [];
var len = str.length;
while (len) {
arr.unshift(str.substring(0, len--));
}
return arr;
}

Why does my function return only one item that matches the criteria?

I am new to javascript and I am working on a coding challenge that requires you to build a function that takes an array of strings as an argument and returns all strings with four letters or characters. My function will return the first four-character item it finds, but then stops and will not return any more four-character items. The code is as follows:
function isFourLetters(arr) {
for (i=0; i < arr.length; i++) {
if (arr[i].length===4) {
return arr[i];
}
}
}
I stared at this for 10 minutes or so trying to see why the for-loop just stops once it reaches an array element with four characters, and for whatever reason I just cannot see it and it makes me think there is something about for-loops that I clearly don't understand. Any help would be greatly appreciated!
Your function is returning the first match (string with 4 letters).
You need to store those matches into an array
function isFourLetters(arr) {
for (i=0; i < arr.length; i++) {
if (arr[i].length===4) {
return arr[i]; // <--- Here your problem
}
}
}
An alternative is pushing the matches into an array:
function isFourLetters(arr) {
var matcher = [];
for (i=0; i < arr.length; i++) {
if (arr[i].length===4) {
matches.push(arr[i]);
}
}
return matches;
}
Or better, take a look at the function filter:
function isFourLetters(arr) {
return arr.filter(function(str) {
return str.length === 4;
});
}
you may declare a "tmpArr" and add 4-letter strings as the loop finds. then return the"tmpArr" at the end of the function.
The problem is that when you enter the if condition you do a return. The return breaks the function scope and returns only arr[i].
You should create a new array inside the function and then use the if to add elements on the returning array. Then, when the for loop ends you can return the whole new array.
You can user filter method in array.The filter() method creates a new array with all elements that pass the test implemented by the provided function.
var arr = ['1234','spray', 'limit',test', 'elite', 'exuberant', 'destruction', 'present'];
const result = arr.filter(arrElement => arrElement.length === 4);
console.log(result);
// Result : [1234,test]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Why is my code pushing every permutation twice?

I'm confused as to why my code is pushing every permutation twice. Please someone help. I'm using heap's algorithm:
var regex = /(.)\1+/g;
function permAlone(str) {
var newArray = str.split('');
var n = newArray.length;
var permutations = [];
var tmp;
function swap(index1, index2) {
tmp = newArray[index1];
newArray[index1] = newArray[index2];
newArray[index2] = tmp;
}
function generate(n, newArray) {
if (n === 1) {
permutations.push(newArray.join(''));
} else {
for(var i = 0; i<n-1; i++) {
generate(n-1, newArray);
swap(n % 2 ? 0 : i, n-1);
permutations.push(newArray.join(''));
}
generate(n-1, newArray);
}
}
generate(n, newArray);
return permutations;
}
permAlone('aab');
The array that is returned is:
["aab", "aab", "aab", "baa", "baa", "aba", "aba", "aba", "baa", "baa"]
So as you can see, the permutations are appearing many more times than intended for each thing. Any help would be great
The code's a little complex and it's difficult to track given the recursion, but if all you want is an array with only unique values, you can simply apply the following code to the result array:
function stripDuplicates(input) {
if (!input || typeof(input) !== 'object' || !('length' in input)) {
throw new Error('input argument is not array.');
}
var newArray = [];
for (var i = 0; i < input.length; i++) {
if (newArray.indexOf(input[i]) === -1) {
newArray.push(input[i]);
}
}
return newArray;
}
This could also be done functionally rather than imperatively, but that's really more of a preference than an optimization issue.
Bálint also points out that you could merely convert the result to a Set, then convert the Set back to an Array, which would automatically strip out any duplicates. Beware, though, that Set is a comparatively new affordance in Javascript and will not function in pre-ES6 environments.
You have a call to:
permutations.push(newArray.join(''));
inside of your for loop. That shouldn't be there. And then, of course if you are permuting strings that have duplicate characters, well, expect to see dupes. e.g., if you permute the string "aa" you'll get two entries from this algorithm "aa" and "aa". Heap's algorithm doesn't try to remove dupes, it treats each element as unique within the string. Obviously, it's trivial to use remove dupes if that's something you care about doing.

How to convert a string to an array based on values of another array in JavaScript

I have some data that I'm trying to clean up. For the field in question, I know what the possible values are, but the value is stored in a concatenated string and I need them in an array. Here is what I would like to do:
var valid_values = ['Foo', 'Bar', 'Baz'];
var raw_data = ['BarFoo','BazBar','FooBaz'];
desired_result = [['Bar','Foo'],['Baz','Bar'],['Foo','Baz']];
I'm not sure what this is called, so I hope this isn't a duplicate.
You can iterate over each data value, searching for allowed string with indexOf or contains and returning successful matches as array.
Here's my version of code and working example at jsFiddle:
var out = raw_data.map(function (raw) {
return valid_values.filter(function (value) {
return raw.contains(value);
});
});
//out === [['Bar','Foo'],['Baz','Bar'],['Foo','Baz']];
I assumed that output match order isn't important.
This is assuming some things about your data:
you need to split strings into 2-item pairs
input & terms are case-sensitive
you won't be dealing with null/non-conforming inputs (requires more edge-cases)
In that case, you'd want to do something like this:
// for each item in the desired result, see if it's a match
// at the beginning of the string,
// then split on the string version of the valid value
function transform(input){
for(i = 0; i < len; i++) {
if (input.indexOf(valid_values[i]) === 0) {
return [ valid_values[i], input.split(valid_values[i])[1] ];
}
}
return [];
}
// to run on your input
var j = 0, raw_len = raw_data.length, desired_result = [];
for(; j < raw_len; j++) {
desired_result.push(transform(raw_data[j]));
}
This code is pretty specific to the answer you asked though; It doesn't cover many edge cases.

Categories

Resources