How to compare every number in an array against each other? (javascript) - javascript

I have a set of numbers which are displayed like followed;
var data = "615:415,600:400,600:400,300:300"
Each number represents an x/y coordinate, and I would like to add a value next to each one which is calculated based on the frequency of the number within a range.
So, I would like to be able to compare each value against all others in this string, and from this perform the following functions;
Remove the number from the string if it is a duplicate, and add :1
If the x/y numbers are both within a range of 15 against any other number, add:1
If there are no matches, add :0
Turn into array
So using the data string, it would be transformed to;
var data = "615:415:1, 600:400:2, 300:300:0"
I have been trying to do this using a reducer function, but I'm struggling with mainly step 2. I'm hoping someone can help out?
Thanks - Code + Plunk below!
http://plnkr.co/edit/zPW1844cLnUFAlEI77jq?p=preview
var result = [];
var data = "615:415,600:400,600:400,300:300"
var count = 0;
var reducer = function(p, c, i, a) {
if (p && p !== c) {
var _t = p.split(":");
result.push({
x: _t[0],
y: _t[1],
value: count
});
count = 0;
if (i === a.length - 1) {
_t = c.split(":");
result.push({
x: _t[0],
y: _t[1],
value: count
});
}
}
else {
count++;
}
return c
}
data.split(',').sort().reduce(reducer);
console.log(result)

You could use a step-by-step approach and split the string first in coordinates, generate a hash table for the coordinates with count and filter only unique coordinates.
Then compare each unique coordinates with each other and count if inside of a given range.
Later map the coordinates with the count and join to string.
var data = "615:415,600:400,600:400,300:300",
result = function (array) {
var i, j,
hash = Object.create(null),
unique = array.split(',').filter(function (a) {
var parts = a.split(':');
if (!hash[a]) {
hash[a] = [parts[0], parts[1], 0]; // [x, y, count]
return true;
}
hash[a][2]++;
});
for (i = 0; i < unique.length - 1; i++) {
for (j = i + 1; j < unique.length; j++) {
if (
Math.abs(hash[unique[i]][0] - hash[unique[j]][0]) <= 15 &&
Math.abs(hash[unique[i]][1] - hash[unique[j]][1]) <= 15
) {
hash[unique[i]][2]++;
hash[unique[j]][2]++;
}
}
}
return unique.map(function (a) {
return hash[a].join(':');
}).join(', ');
}(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Here's an alternative:
var data = "615:415,600:400,600:400,300:300";
var result = (function (s) {
var result = {};
var values = [];
// Process each value
s.split(',').forEach(function (v) {
var b = v.split(':');
// If a match, increment count by 2 (once for match and again for within 15)
if (result[v]) {
result[v].count += 2;
// Otherwise, just check for within 15
} else {
result[v] = {x:b[0], y:b[1], count:0};
values.forEach(function(xy, i){
if (xy[0]>= (b[0]-15) && xy[0] <= (+b[0]+15) &&
xy[1]>= (b[1]-15) && xy[1] <= (+b[1]+15) ) {
++result[xy.join(':')].count; // Increment for nearby only
}
})
values.push([b[0],b[1]]);
}
})
// Create required string format
return Object.keys(result).reduce(function(arr, key){
arr.push(key + ':' + result[key].count);
return arr;
},[]).join(', ');
})(data)
console.log(result);

All answers so far are good. I just would like to introduce a little variety by inventing an Array.prototype.withEachOther() method. Which just takes a callback an invokes the callback with each other item of the array being it's arguments as you may suggest. It works in place.
Array.prototype.withEachOther = function(cb){
this.map(function(e,i,a){
var t = a.slice();
t.splice(0,i+1);
t.map(function(f){
a[i] = cb(e,f);
});
});
return this;
};
var data = "615:415,600:400,600:400,300:300, 550 : 550".split(/\s*,\s*/)
.map(s => s.split(/\s*:\s*/).concat(0)),
cb = (f,s) => (Math.abs(f[0]-s[0]) <= 15 && Math.abs(f[1]-s[1]) <= 15 && (f[2]++, s[2]++),f);
result = data.reduceRight(function(p,c,i,a){
var fi = a.slice(0,i-a.length)
.findIndex(f => f[0] === c[0] && f[1] === c[1]);
fi !== -1 ? (a[fi][2] += ++c[2], a.splice(i,1))
: p.push(c);
return p;
},[])
.withEachOther(cb)
.reduce((p,c) => p += c[0]+":"+c[1]+":"+c[2]+", ","");
console.log(result);

Related

Shorten array if total length of strings is longer than specified value (for loop) - JavaScript

I'm trying to shorten a text, if it is longer than a specified number.
So shorten_text_easy(text, 30), should return "We believe. In the future".
The first loop is working and displaying the correct total length of the strings in the array, but the second is where the error is, but I can't seem to find the issue.
var text = "We believe. In the future. The future is here. This is a test. We are testing.";
function shorten_text_easy(text, number) {
var text_array = text.split('. ').join('.///').split('///'); // Splitting the text into an array
var text_array_length = text_array.length;
var total_text_array_length = 0; // Predefining value to zero; The total length of all strings in the array
for (var i = 0; i < text_array_length; i++) { // To run while i is short than the length of the array
total_text_array_length += text_array[i].length; //
}
total_text_array_length = total_text_array_length + text_array_length - 1; // To exclude spaces which are omitted in array
console.log(total_text_array_length); // To show in console the first value of total_array_length
for (total_text_array_length; total_text_array_length > number; text_array.pop(-1), text_array_length--) { // Trying to remove the last item of an array if the total length of all strings in the array is larger than the number
for (var i = 0; i < text_array_length; i++) {
total_text_array_length += text_array[i].length;
console.log(total_text_array_length);
}
total_text_array_length = total_text_array_length + text_array_length - 1;
}
return text_array // This should return the end text array, when the total length of all strings is lower than 'number'
};
console.log(
shorten_text_easy(text, 30)
);
Slicing on last full stop that fits
const shorten_text_easy = (text, number) => {
let res = text.slice(0,number);
const pos = res.lastIndexOf(".");
return pos > 0 ? res.slice(0,pos+1) : res;
}
var text = "We believe. In the future. The future is here. This is a test. We are testing.";
console.log(
shorten_text_easy(text, 30)
);
I ended up doing this:
function shortenTextNextDot (text, length) {
var firstDot = text.indexOf(".") + 1;
if (length <= firstDot) {
return text.slice(0, firstDot);
} else {
var textLength = text.slice(0, length);
var restText = text.slice(length);
var nextDot = restText.indexOf(".") + 1;
var finalSentence = textLength + restText.slice(0, nextDot);
return finalSentence;
}
}
function shortenTextPrevDot (text, length) {
var firstDot = text.indexOf(".") + 1;
if (length <= firstDot) {
return text.slice(0, firstDot);
} else {
var textLength = text.slice(0, length);
var lastDot = textLength.lastIndexOf(".") + 1;
var finalSentence = textLength.slice(0, lastDot);
return finalSentence;
}
}

How can I create a unique ID

I have a grid to which I can add or remove data For add I have this method
handelAddValueTransactionInput() {
let valueTransaction = this.state.valueTransaction;
valueTransaction.push({ id: valueTransaction.length + 1,Value:this.state.valueTransactionInput });
this.setState({ valueTransaction, valueTransactionInput: '' })
}
for delete:
deleteValueTransaction(data) {
let indexOfDeleted = -1;
let valueTransaction = this.state.valueTransaction;
this.state.valueTransaction.forEach((item, index) => {
if (item.id === data.id) {
indexOfDeleted = index;
}
})
valueTransaction.splice(indexOfDeleted, 1);
this.setState({
valueTransaction: valueTransaction
});
}
My problem is that when I have 3 data and I delete the second one and add one data twice .. the data that is added creates the same ID as the previous one
How can I create a unique ID for each?
You can use UUID
function create_UUID() {
var dt = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (dt + Math.random() * 16) % 16 | 0;
dt = Math.floor(dt / 16);
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
return uuid;
}
for (let i = 0; i < 10; i++)
console.log(create_UUID());
If you want a random string, search for a "random string generator in JavaScript", I don't have it open now but there is such a function on another stack overflow question. One of the answers gives a nice function that returns a random string
For ids with length < 15 you can use following formula and combine it for large strings.
getRandomString = (length) => {
return Math.random().toString(36).substring(2, length + 2)
}

print like this * "a" -> "a1" * "aabbbaa" -> "a2b3a2"

I am new to js.
can you tell me how to print like this * "a" -> "a1" * "aabbbaa" -> "a2b3a2"
i tried with hash map but test cases failing.
providing my code below.
i am not good in hash map.
can you tell me how to solve with hash map so that in future I can fix it my self.
not sure what data structure to use for this one.
providing my code below.
const _ = require("underscore");
const rle = ( input ) => {
console.log("input--->" + input);
//var someString ="aaa";
var someString = input;
var arr = someString.split("");
var numberCount = {};
for(var i=0; i< arr.length; i++) {
var alphabet = arr[i];
if(numberCount[alphabet]){
numberCount[alphabet] = numberCount[alphabet] + 1;
}
else{
numberCount[alphabet] = 1;
}
}
console.log("a:" + numberCount['a'], "b:" + numberCount['b']);
}
/**
* boolean doTestsPass()
* Returns true if all the tests pass. Otherwise returns false.
*/
/**
* Returns true if all tests pass; otherwise, returns false.
*/
const doTestsPass = () => {
const VALID_COMBOS = {"aaa": "a3", "aaabbc":"a3b2c1"};
let testPassed = true;
_.forEach(VALID_COMBOS, function(value, key) {
console.log(key, rle(key));
if (value !== rle(key)) {
testPassed = false;
}
});
return testPassed;
}
/**
* Main execution entry.
*/
if(doTestsPass())
{
console.log("All tests pass!");
}
else
{
console.log("There are test failures.");
}
You could
match groups of characters,
get the character and the count and
join it to a string.
function runLengthEncoding(string) {
return string
.match(/(.)\1*/g) // keep same characters in a single string
.map(s => s[0] + s.length) // take first character of string and length
.join(''); // create string of array
}
console.log(['a', 'aaa', 'aaabbc'].map(runLengthEncoding));
This is a bit more understandable version which iterates the given string and count the characters. If a different character is found, the last character and count is added to the result string.
At the end, a check is made, to prevent counting of empty strings and the last character cound is added to the result.
function runLengthEncoding(string) {
var result = '',
i,
count = 0,
character = string[0];
for (i = 0; i < string.length; i++) {
if (character === string[i]) {
count++;
continue;
}
result += character + count;
character = string[i];
count = 1;
}
if (count) {
result += character + count;
}
return result;
}
console.log(['', 'a', 'aaa', 'aaabbc'].map(runLengthEncoding));
You can reduce the array into a multidimensional array. map and join the array to convert to string.
const rle = (input) => {
return input.split("").reduce((c, v) => {
if (c[c.length - 1] && c[c.length - 1][0] === v) c[c.length - 1][1]++;
else c.push([v, 1]);
return c;
}, []).map(o => o.join('')).join('');
}
console.log(rle("a"));
console.log(rle("aabbbaa"));
console.log(rle("aaaaaa"));
Your function rle doesn't return a result.
Also note, this implementation may pass the test cases you wrote, but not the examples you mentioned in your question: for the string "aabbaa" this will produce "a4b2", not " a2b2a2" .
A simpler solution:
function runLengthEncoding(str) {
let out = "";
for (let i = 0; i < str.length; ++i) {
let temp = str[i];
let count = 1;
while (i < str.length && str[i+1] == temp) {
++count;
++i;
}
out += temp + count;
} // end-for
return out;
}
console.log(runLengthEncoding("a"));
console.log(runLengthEncoding("aabbbaa"));
console.log(runLengthEncoding("aaaaaa"));

Find the longest occurrence of the "aeiou" in a string

I was recently doing an interview and was asked multiple questions, one of the questions was this and I had a bit of trouble trying to answer it.
Given a string, find the longest occurrence of vowels "aeiou" that appear.
The substring of vowels do not have to be consecutive, and there can be repeats.
The goal is the find the max occurrence of each vowel and join them, but it must be in the order of "a","e","i","o","u".
Edit: In addition, each individual vowel character must be chained as well. In the example below, there is "aaa" and "aa" , since 3 is longer, our result must contain the longer chain.
For example:
Input: "aaagtaayuhiejjhgiiiouaae"
Result: aaaeiiiou
The code that I have tried is below:
EDIT: Following the solution, I have written this below but I am still running into issues with strings such as "aeiouaaaeeeiiiooouuu". The correct result for that would be 15 but I am getting 5.
var findLongestVowels = function(s){
var count = 1;
var i = 0;
var j = 0;
var vowels = ['a','e','i','o','u'];
var total = 0;
var array = [];
while (i < s.length){
if (s.charAt(i) == vowels[j] && s.charAt(i) == s.charAt(i+1) ){
count++;
}
else if (s.charAt(i) == vowels[j] && s.charAt(i) != s.charAt(i+1)){
if (j === 0 && !array[vowels[j]]){
array[vowels[j]] = count;
}
else if (j === 0 && array[vowels[j]]){
array[vowels[j]] = Math.max(array[vowels[j]],count);
}
else if (j !== 0 && !array[vowels[j]] && array[vowels[j-1]]){
array[vowels[j]] = array[vowels[j-1]] + count;
}
else if (j !== 0 && array[vowels[j]] && array[vowels[j-1]]){
array[vowels[j]] = Math.max(array[vowels[j]],array[vowels[j-1]] + count);
}
count = 1;
}
else if (s.charAt(i) == vowels[j+1] && array[vowels[j]]){
j++;
i--;
}
i++;
}
console.log(array);
console.log('Answer: ' + array[vowels[j]]);
}
findLongestVowels("eeeeebbbagtaagaaajaaaaattyuhiejjhgiiiouaae");
Am I at least going in the right direction?
Thanks in advance.
We can solve this in O(n) time. Consider that for each block, if its vowel is at index v in the list of vowels, we are only interested in the best solution for the block with a vowel at index v-1 in the order of vowels. We save the last best solution for each block type (each vowel) as we go along:
|aaa|g|t|aa|y|u|h|i|e|jj|h|g|iii|o|u|aa|e
b: 1 2 3 4 5 6 7 8 9 10
b 1: v[a] = 3
b 2: v[a] = max(2,3)
b 3: v[u] = None recorded for v-1
b 4: v[i] = None recorded for v-1
b 5: v[e] = 1 + 3
b 6: v[i] = 3 + 4
b 7: v[o] = 1 + 7
b 8: v[u] = 1 + 8 // answer
b 9: v[a] = max(2,3)
b 10: v[e] = 1 + 3
JavaScript code:
function f(str){
console.log(`String: ${ str }\n`);
var vowels = {
a: {best: 0, prev: null},
e: {best: 0, prev: 'a'},
i: {best: 0, prev: 'e'},
o: {best: 0, prev: 'i'},
u: {best: 0, prev: 'o'}
};
function getBlock(i){
let length = 1;
while (str[i+1] && str[i] == str[i+1]){
length++;
i++;
}
return length;
}
for (let i=0; i<str.length;){
let length = getBlock(i);
console.log(`i: ${ i }; length: ${ length }`)
if (!vowels[str[i]]){
i = i + length;
continue;
}
if (!vowels[str[i]].prev){
vowels[str[i]].best = Math.max(
vowels[str[i]].best,
length
);
// make sure the previous vowel
// exists in the string before
// this vowel
} else if (vowels[ vowels[str[i]].prev ].best){
vowels[str[i]].best = Math.max(
vowels[str[i]].best,
length + vowels[ vowels[str[i]].prev ].best
);
}
i = i + length;
}
console.log(`\n${ JSON.stringify(vowels) }\n\n`);
return vowels['u'].best;
}
var s = 'eeeeebbbagtaagaaajaaaaattyuhiejjhgiiiouaae';
console.log(f(s) + '\n\n');
s = 'aaagtaayuhiejjhgiiiouaae';
console.log(f(s) + '\n\n');
s = 'aeiouaaaeeeiiiooouuu';
console.log(f(s));
This problem can be solved by using dynamic programming technique.
First, we have string x and we want to find the longest string for this string.
Traversing the string x from start to end, assuming at index i, we are trying to find vowel e, there are two possibilities:
Current character is e, so we take the whole block and move to next character
Or, we can try with the next character
So, we have our pseudocode:
int[][]dp;
int largestBlock (int index, int currentVowel, String x, String vowels){
if (currentVowel == 5) {
// We found all 5 vowel
return 0;
}
if visited this state (index, currentVowel) before {
return dp[index][currentVowel];
}
int result = largestBlock(index + 1, currentVowel, x, vowels) ;
if (x[index] == vowels[currentVowel]){
int nxt = nextIndexThatIsNotVowel(index, currentVowel, x, vowels);
result = max(result, nxt - index + largestBlock(nxt, currentVowel + 1, x , vowels));
}
return dp[index][currentVowel] = result;
}
Time complexity is O(n * m) with m is number of vowels which is 5 in this case.
You need to remember biggest combination of individual vowels.
Use reduce, map and Object.values
var vowels = "aeiou";
var input = "aaagtaayuhiejjhgiiiouaae";
var output = Object.values(
input.split( "" ).reduce( ( a, c, i, arr ) => {
var lastChar = arr[ i - 1 ];
if ( !vowels.includes( c ) ) return a; //if not vowel, return accumulator
if ( c != lastChar ) //if not same as last character then create a new array
{
a[ c ] = a[ c ] || [];
a[ c ].push( [ c ] );
}
else //else push to the last array;
{
var lastCombo = a[ c ].slice( -1 )[ 0 ];
lastCombo.push(c)
}
return a; //return accumulator
} , {}) ).map( s => {
var char = s[0][0]; //find the character to repeat
var maxLength = Math.max.apply( null, s.map( s => s.length ) ); //find how many times to repeat
return Array( maxLength + 1 ).join( char );
}).join( "" ); //join all the vowels
console.log( output );
It's just one of many possible solutions - feel free to try it out.
Store every vowel you're interested in, in vowels array.
Use map to loop over every vowel in array, create regex from vowel to split string into array of vowels. For example "aaabdmedaskaa" would be split into ["aaa", "a", "aa"].
Filter this array so it doesn't include empty strings.
Sort it by length, so accesing 0 element would give you longest occurance
After mapping over every vowel, return the result - filter out "undefined" in case some of your vowels don't occur at all and regex results in empty array (accesing empty array's 0th element would result in undefined), join array of occurances into a result string.
The regex created from "a" will be [^a]+ which means any character sequence that does not include "a".
function findLongestOccurance(str) {
const vowels = ["a", "e", "i", "o", "u"];
const result = vowels.map(vowel => {
const regex = new RegExp(`[^${vowel}]+`);
return str.split(regex)
.filter(r => r !== "")
.sort((a, b) => b.length - a.length)[0];
});
return result.filter(occ => typeof(occ) !== "undefined").join("");
}
console.log(findLongestOccurance("aaagtaayuhiejjhgiiiouaae"));
Why not regex?
var result = /(a+).*(e+).*(i+).*(o+).*(u+)/.exec("aaagtaayuhiejjhgiiiouaae");
console.log(result[1]+result[2]+result[3]+result[4]+result[5]);
First of all, from what I understand from the question the result for Input: "aaagtaayuhiejjhgiiiouaae" should be aaaaaeiiiou, like #PhamTrung asked in the comments but didn't get answered.
Because it a job interview I would start with the first thing that comes to mind, namely brute force the solution out of this
function a(string, prefix='') {
if(!string.length){
return prefix
}
if(!/[aeiou]/.test(string[0])){
return a(string.substr(1), prefix)
}
const option1 = a(string.substr(1), prefix)
const option2 = a(string.substr(1), prefix+string[0])
const validateRegex = /^a+e+i+o+u+$/
const isValidOption1 = validateRegex.test(option1)
const isValidOption2 = validateRegex.test(option2)
if(isValidOption1 && isValidOption2){
if(option1.length > option2.length) {
return option1
}
return option2
}
if(isValidOption1) {
return option1
}
if(isValidOption2) {
return option2
}
return null
}
const input = 'aaagtaayuhiejjhgiiiouaae'
console.log(a(input))
This has a terrible run time though, we are trying all possible substring that contains only vowels, than we are discarding those that aren't of the form required (a+e+i+o+u+) and than choosing only the biggest of them all. If I'm not mistake this has a worst case of ∑(n choose i) which is O(n^n) - well, the actual worst case here would be a stackOverflow exception for sufficiently large n in which case we'd have to reimplement this with a loop instead of recursing. In this case we could still get an out of memory exception in which case we'd be out of options but to improve our algorithm. It's fair to imagine that if the input were large enough that we got an out of memory exception than our code would also be slow enough to not be a reasonable solution to the problem. I'm just arguing all this because these are things that an interviewer would possibly like to see that you are aware of, meaning you know enough of CS 101.
Following that the interviewer would ask if I can improve the performance. This is a solution with running time of O(n).
const input = 'aeiouaaaeeeiiiooouuu'
let curr = { "1": {price: -1} }
const nodes = []
const voewels = '1aeiou'
const getPrevLetter = (node) => voewels[voewels.indexOf(node.letter) -1]
let resultNode
function setUpNodeByCurrent(node, letter){
node.price = curr[letter].price + 1
node.previous = curr[letter]
}
function setBestResultIfNeeded(node){
if(node.letter !== 'u') {
return
}
if(!resultNode || resultNode.price < node.price) {
resultNode = node
return
}
}
function setCurrent(letter){
const node = {
letter,
price: 0
}
const prevLetter = getPrevLetter(node)
if(!prevLetter || !curr[prevLetter]){
// either letter isn't on of aeiou or
// we got to an i without ever seeing an e, an o without ever seeing an i, ... this letter is irrelevant
return
}
if(curr[node.letter]) {
setUpNodeByCurrent(node, node.letter)
}
if(node.price < curr[prevLetter].price + 1) {
setUpNodeByCurrent(node, prevLetter)
}
curr[node.letter] = node
setBestResultIfNeeded(node)
}
function getStringResult(node){
let result = ''
while(node) {
result = node.letter + result
node = node.previous
}
return result
}
function getResult(){
const node = resultNode //getBestResultNode()
const result = getStringResult(node)
console.log(result)
console.log(result.length)
}
for(let l of input){
setCurrent(l)
}
getResult()
This can be seen as a simplification of the longest path problem over a DAG basically you'd run through the string and every a points to the next occurance of a and the next occurance of e. e points to the next e and to the next i and so on. You'd than have a start node pointing to every occurance of a and an end node pointed to by every occurance of u. Now what you want is the longest path from the start node to the end node which is an O(|V|+|E|), now |V|<=n and |E|<=2n since every node in your graph has at most 2 vertices going out of it so the total running time is O(n). I have simplified the code to build the result as it goes on building the graph, basically I already calculate the cost on the go so when I finished building a graph similar to what I described I already know what the result is.
Note that this solution is based on the assumption that the input string is one that necessarily has a solution embedded in it. If the input string is unsolvable (there isn't and aeiou sequence in it) than this case would need to be properly handled, it is actually trivial to add the code that handles that. The first solution will return null in such a case(if I'm not mistaken)
Hope this helps.
If you want to find a substring which contains the maximum number of vowels and you also want to give {specify} the length of the substring then you should use this program:
let newk = s;
const elementsArray = [];
const tempoArray = [];
const counting = [];
const maxPoint = [];
let count
for (var i = 0; i < newk.length; i++) {
while (tempoArray.length > 0) {
tempoArray.pop();
}
let fk = i + k;
if (fk <= newk.length) {
for (let j = i; j < fk; j++) {
tempoArray.push(newk[j]);
}
let makingArray = tempoArray.toString();
elementsArray.push(makingArray);
} else {
// console.log(" ");
}
}
for (let q = 0; q < elementsArray.length; q++) {
count = 0
let tempString = new String(elementsArray[q]).split(",")
for (let l = 0; l < tempString.length; l++) {
if (tempString[l] == "a" || tempString[l] == "e" || tempString[l] == "i" || tempString[l] == "o" || tempString[l] == "u") {
count ++;
}else{
}
}
// console.log(count);
counting.push(count)
}
let max = 0,Maximist
// for (let d = 0; d < counting.length; d++) {
// console.log(counting[d] , " this is the value of the counting array");
// }
for (let t = 0; t <= counting.length; t++) {
if (counting[t] != 0) {
if (max < counting[t]) {
max = counting[t]
Maximist = t
}
else if (max == counting[t]){
max = counting[t]
Maximist = t
}
else{
console.log("");
}
}
}
// console.log(Maximist);
// console.log(max);
// maxPoint.push(Maximist)
for (let t = 0; t <= counting.length; t++) {
if (counting[0] != 0) {
if (max == counting[t]) {
maxPoint.push(t)
}
}
}
for (let e = 0; e < maxPoint.length; e++) {
console.log("{", elementsArray[maxPoint[e]] ,"}")
}
}
findSubstring("captainamerica", 3);
The bigger your size of the substring will be the less chances that there will be less substring with same number of vowels in it

How do I access JQuery property inside a usual JS function

I have a function which takes an array as an argument and later process it and change values of this array. The problem is that the array was made of JQuery nodes(usual span), and I access this span value by calling .text() JQuery method. Here's how it looks:
var array=
[
$('*[id$=id1]'),
$('*[id$=id2]'),
$('*[id$=id3]'),
$('*[id$=id4]'),
$('*[id$=id5]')
] // Ignore the weird way of the selectors. It's just a feature of back-end technology I use
function removeZeros(arr)
{
var map = arr.map(function(a) {
//logic to perform...
}
arr.forEach(function(value, index, arr)
{
arr[index] = Number.parseFloat(value).toFixed(maxNum);
});
//Rewriting the values..
}
}
removeZeros(array)
In the example above I get an exception since the values which are stored in the array are just plain HTML code. The real value I access using .text() as I mentioned earlier. So I need to make the a in the function call this method.
I've tried (function($(a).text(), (function($(a.text()) and (function($a.text()) so far, but nothing seems to work, it throws a nasty exception of unexcepted literal. How do I access text() anyway?
Whole function:
function removeZeros(arr)
{
var map = arr.map(function(a)
{
if (a % 1 === 0)
{
var res = "1";
}
else
{
var lastNumman = a.toString().split('').pop();
if (lastNumman == 0)
{
var m = parseFloat(a);
var res = (m + "").split(".")[1].length;
}
else
{
var m = a.split(".")[1].length;
var res = m;
}
}
return res;
});
var maxNum = map.reduce(function(a, b) {
return Math.max(a, b);
});
arr.forEach(function(value, index, arr) {
arr[index] = Number.parseFloat(value.text()).toFixed(maxNum);
});
}
In the example above I get an exception since the values which are stored in the array are just plain HTML code.
No, they're jQuery instances. Calling Number.parseFloat on a jQuery instance is going to return NaN*.
You don't need to do anything special if you want to access the text, the entry is a jQuery object, just call .text() on it directly:
arr[index] = Number.parseFloat(value.text()).toFixed(maxNum);
// ---------------------------------^^^^^^^
* (because parseFloat will coerce the object to string, getting "[object Object]", and "[object Object]" cannot be parsed to a float)
Having seen the full function, as you said in a comment, you'll want to use .text on a as well. Here's that and some other notes:
function removeZeros(arr) {
var map = arr.map(function(a) {
var res, astNumman, m;
// *** Get the text of the entry
a = a.text();
if (a % 1 === 0) { // *** ? `a` is a string. This will coerce it to number and then do % on it.
res = "1";
} else {
lastNumman = a[a.length-1]; // *** Much more efficient than `a.split('').pop();`
if (lastNumman == 0) { // *** Again using a string as a number
m = parseFloat(a);
res = (m + "").split(".")[1].length; // *** The *length* of the fractional portion?
} else {
m = a.split(".")[1].length;
res = m;
}
}
return res;
});
var maxNum = map.reduce(function(a, b) {
return Math.max(a, b);
});
// ***
arr.forEach(function(value, index, arr) {
arr[index] = Number.parseFloat(value.text()).toFixed(maxNum);
});
}
Running Example:
var array=
[
$('*[id$=id1]'),
$('*[id$=id2]'),
$('*[id$=id3]'),
$('*[id$=id4]'),
$('*[id$=id5]')
];
function removeZeros(arr) {
var map = arr.map(function(a) {
var res, astNumman, m;
// *** Get the text of the entry
a = a.text();
if (a % 1 === 0) { // *** ? `a` is a string. This will coerce it to number and then do % on it.
res = "1";
} else {
lastNumman = a[a.length-1]; // *** Much more efficient than `a.split('').pop();`
if (lastNumman == 0) { // *** Again using a string as a number
m = parseFloat(a);
res = (m + "").split(".")[1].length; // *** The *length* of the fractional portion?
} else {
m = a.split(".")[1].length;
res = m;
}
}
return res;
});
var maxNum = map.reduce(function(a, b) {
return Math.max(a, b);
});
// ***
arr.forEach(function(value, index, arr) {
arr[index] = Number.parseFloat(value.text()).toFixed(maxNum);
});
}
removeZeros(array);
console.log(array);
<div id="id1">7</div>
<div id="id2">6.4324</div>
<div id="id3">8.24</div>
<div id="id4">8998.3</div>
<div id="id5">0</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
It seems like the goal of removeZeroes is to convert the array of jQuery objects into an array of strings with the text of the object converted to number and then to string where they all have the same number of digits after the decimal (the longest one). If so, we can be a bit more efficient about it:
function removeZeros(arr) {
// Find longest decimal portion, convert jQuery objects to numbers
var longest = -Infinity;
arr.forEach(function(entry, index) {
var num = parseFloat(entry.text());
var str = String(num);
var decimal = str.indexOf(".");
var thisLength;
if (decimal === -1) {
thisLength = 1;
} else {
thisLength = str.length - decimal - 1;
}
if (thisLength > longest) {
longest = thisLength;
}
arr[index] = num;
});
// Format numbers as strings
arr.forEach(function(num, index) {
arr[index] = num.toFixed(longest);
});
}
Running Example:
var array=
[
$('*[id$=id1]'),
$('*[id$=id2]'),
$('*[id$=id3]'),
$('*[id$=id4]'),
$('*[id$=id5]')
];
function removeZeros(arr) {
// Find longest decimal portion, convert jQuery objects to numbers
var longest = -Infinity;
arr.forEach(function(entry, index) {
var num = parseFloat(entry.text());
var str = String(num);
var decimal = str.indexOf(".");
var thisLength;
if (decimal === -1) {
thisLength = 1;
} else {
thisLength = str.length - decimal - 1;
}
if (thisLength > longest) {
longest = thisLength;
}
arr[index] = num;
});
// Format numbers as strings
arr.forEach(function(num, index) {
arr[index] = num.toFixed(longest);
});
}
removeZeros(array);
console.log(array);
<div id="id1">7</div>
<div id="id2">6.4324</div>
<div id="id3">8.24</div>
<div id="id4">8998.3</div>
<div id="id5">0</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
There I've used your arr.forEach-assign-to-arr[index] pattern rather than map as you seemed to prefer it (and it does avoid creating two unnecessary arrays).

Categories

Resources