First of all sorry for bothering with a question asked several times before.But I have to say that I did read through the related questions about string permutations and I could not figure out the actual problem with the code I have below. I want to return the combinations of a string.Please help me out in finding the mistake ! PS: I have just started learning javascript!
var result = [];
function doPerm(prefix, suffix, result) {
if (suffix.length === 0)
result.push(prefix);
else {
for (i = 0; i < suffix.length; i++) {
doPerm(prefix + suffix.charAt(i), suffix.slice(0, i) + suffix.slice(i + 1), result);
}
}
}
function permAlone(str) {
var prefix = "";
var suffix = str;
doPerm(prefix, suffix, result);
return result;
}
console.log(permAlone('aab'));
INPUT:'aab'
OUTPUT:[aab,aab,aba,aba,baa,baa]
Your logic was correct actually, you just declared i without var in for loop which made it global and was giving you errors. It seems to be working once that is corrected:
var result = [];
function doPerm(prefix, suffix, result) {
if (suffix.length === 0)
result.push(prefix);
else {
for (var i = 0; i < suffix.length; i++) {
doPerm(prefix + suffix.charAt(i), suffix.slice(0, i) + suffix.slice(i + 1), result);
}
}
}
function permAlone(str) {
var prefix = "";
var suffix = str;
doPerm(prefix, suffix, result);
return result;
}
console.log(permAlone('aab'));
This is a bit of on the back of a piece of paper thinking but.
for(i;i<string.length;i++) {
var s = string.slice(i,i+1);
var c = string.charAt(i);
var q = s.split("");
for(b=0;b<q.length;b++) {
var newArray = q.slice();
newArray.splice(b,0,c);
result.push(newArray.join());
}
}
does that work?
UPDATE this seems to work!
<script>
var string = "aab";
var result = [];
for(i=0;i<string.length;i++) {
var c = string.charAt(i);
var q = string.split("");
q.splice(i,1);
console.log("first");
console.log(q);
console.log(c);
for(b=0;b<q.length;b++) {
var newArray = q.slice();
newArray.splice(b,0,c);
result.push(newArray.join());
}
}
console.log(result);
</script>
Related
im here to ask, if someone can help me with quotation and syntax checking.
im aware of the question solution 1, but i don't fully understand that solution.
here is an example, fully integrated into a website and humbly ask, if anyone can find an error?
function rewriteQuotes(){
var all_p = document.querySelectorAll(`.content_container`);
var regex_s = /[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?#\[\]^_`{|}~]/;
for (var i = 0; i < all_p.length; i++) {
if (all_p[i] != null) {
var all_nodes = all_p[i].querySelectorAll("*");
for (var k = 0; k < all_nodes.length; k++) {
if (all_nodes[k].childNodes.length > 0) {
var all_children = all_nodes[k].childNodes;
for (var t = 0; t < all_children.length; t++) {
if (all_children[t].nodeName == "#text") {
all_children[t].textContent = all_children[t].textContent.replace(/"/g,"\“");
all_children[t].textContent = all_children[t].textContent.replace(/\s\“/g,"\ „");
if (all_children[t].textContent.charAt(0)== "\“") {
if (all_children[t].textContent.charAt(1) === "") {
} else {
var char_1 = all_children[t].textContent.charAt(1);
if (regex_s.test(char_1)) {
} else {
all_children[t].textContent = "\„" + all_children[t].textContent.substring(1);
}
}
}
}
}
}
}
}
}
};
document.addEventListener('DOMContentLoaded',function(){
setTimeout(function(){
rewriteQuotes();
},1);
});
<div class="content_container">
<h2>"Hello"</h2>
<p>my "aunti" was driving over the "cat" with her "<em>skateboard</em>".</p>
</div>
You can simplify your regex and capture groups of "..." and then replace the quotes of those groups with your desired ones:
const regex = /"(.*?)"/g;
const str = `my "aunti" was driving over the "cat" with her "car"`;
const subst = `„$1“`;
const result = str.replace(regex, subst);
console.log('Original: ', str);
console.log('Result: ', result);
I'm trying to come up with some very reusable code that will look up and perform variable substitutions within a string.
The example string below contains a $$ reference to a variable. Format is varname.key.
I want the subText() function to be reusable. The issue I'm having is repvars themselves can require substitution. The code hasn't finished substituting the example text and I'm asking it to substitute the repvars.cr by calling the same function. This seems to through it off. I'm saying that because if I do it separately in works.
var exampleText = "A string of unlimited length with various variable substitutions included $$repvars.cr$$";
var repvars = {
cr: 'Copyright for this is $$repvars.year$$',
year: '2019'
}
function subText(text) {
var subVars = findSubs(text);
return makeSubs(text, subVars);
}
function findSubs(theText) {
var subarr = [];
while (theText.indexOf('$$') > -1) {
theText = theText.substring(theText.indexOf('$$') + 2);
subarr.push(theText.substring(0, theText.indexOf('$$')));
theText = theText.substring(theText.indexOf('$$') + 2);
}
return subarr;
}
function makeSubs(text, subs) {
for (var s = 0; s < subs.length; s++) {
var subst = getSubVal(subs[s]);
text = text.split("$$" + subs[s] + "$$").join(subst);
}
return text;
}
function getSubVal(subvar) {
var subspl = subvar.split('.');
switch (subspl[0]) {
default:
return processRepVar(subspl[1]);
}
}
function processRepVar(rvName) {
var data = getRepVarData(rvName);
if(data.indexOf('$$') > -1) {
subText(data);
} else {
return data;
}
}
function getRepVars() {
return repvars;
}
function getRepVarData(key) {
return getRepVars()[key];
}
subText(exampleText);
Aren't you just missing a return here?
function processRepVar(rvName) {
var data = getRepVarData(rvName);
if(data.indexOf('$$') > -1) {
subText(data);
} else {
return data;
}
}
Changing subText(data) to return subText(data); makes your code work for me.
Working jsfiddle: https://jsfiddle.net/uzxno754/
Have you tried regular expressions for this?
function replace(str, data) {
let re = /\$\$(\w+)\$\$/g;
while (re.test(str))
str = str.replace(re, (_, w) => data[w]);
return str;
}
//
var exampleText = "A string with variables $$cr$$";
var repvars = {
cr: 'Copyright for this is $$year$$',
year: '2019'
}
console.log(replace(exampleText, repvars))
Basically, this repeatedly replaces $$...$$ things in a string until there are no more.
I wrote my code to search string for keywords and extracting needed data, but I have problems when I'm trying to search with keywords in arrays named: sort, title and artist. When I'm doing it I get an error about potential infinite loop.
var type = ['track','tracks','song','songs','album','albums'];
var artist = ['created by', 'made by'];
var genre = ['genre'];
var limit = ['set limit'];
var title = ['title','name'];
var sort = ['sort by', 'classificate by', 'separate by'];
var sortBy = ['popularity'];
// function changeWordsToNumbers(words) {
// if (msg.numbers[words])
// return msg.numbers[words];
// }
function searchForIndex(instruction, keywords) {
for (i = 0; i < keywords.length; i++) {
let search = instruction.search(keywords[i]);
if (search)
return search;
}
return false;
}
function getSearchResult(wanted) {
var searchResult = {
artist : searchForIndex(wanted, artist),
genre : searchForIndex(wanted, genre),
limit : searchForIndex(wanted, limit),
type : searchForIndex(wanted, type),
title : searchForIndex(wanted, title),
sort : searchForIndex(wanted, sort),
sortBy : searchForIndex(wanted, sortBy)
};
return searchResult;
}
function removeJunkKeyword(searchResult,instruction) {
for(var property in searchResult) {
if(searchResult.hasOwnProperty(property)) {
if(searchResult[property] != - 1) {
instruction = instruction.slice(0, searchResult[property] - 1);
}
}
}
return instruction;
}
function checkExist(searchResult) {
for(var property in searchResult) {
if(searchResult.hasOwnProperty(property)) {
if(searchResult[property] != -1)
return false;
}
}
return true;
}
function findAndCleanQuery(instruction, keywords) {
var exist = instruction.search(keywords);
var result = instruction.slice(exist + keywords.length + 1, instruction.length);
var searchResult = getSearchResult(result);
if (exist != -1) {
if (checkExist(searchResult)) {
return result;
} else {
result = removeJunkKeyword(searchResult,result);
return result;
}
}
return false;
}
function searchFor(instruction, keywords) {
for (i = 0; i < keywords.length; i++) {
let result = findAndCleanQuery(instruction,keywords[i]);
if (result)
return result;
}
return false;
}
function searchForType(instruction) {
for (i = 0; i < type.length; i++) {
let search = instruction.search(type[i])
if(search)
return type[i];
}
return false;
}
function searchForKeywords(instruction) {
msg.artist = searchFor(instruction, artist);
msg.type = searchForType(instruction, type);
msg.genre = searchFor(instruction, genre);
msg.limit = searchFor(instruction, limit);
msg.title = searchFor(instruction, title);
msg.sort = searchFor(instruction, sortreg);
}
var msg = {}
msg.instruction = 'Search for me';
searchForKeywords(msg.instruction);
console.log(msg.artist);
console.log(msg.type);
console.log(msg.genre);
console.log(msg.limit);
console.log(msg.title);
console.log(msg.sort);
Link for code: https://repl.it/J4Mc/9
PS. The object msg is used by node-red to communicate between nodes.
The issue is that you're doing this on several of your loops:
for (i = 0; i < keywords.length; i++) {
...where you should be doing this instead:
for (let i = 0; i < keywords.length; i++) {
Without using let, the variable i is effectively global. Each time you went into a new loop it got reset to 0, so it was never able to increase, which created the infinite loop.
As a side note, you'll also notice sortreg is undefined when it's used on line 98.
I'd like to extend javascript to add custom type checking.
e.g.
function test(welcome:string, num:integer:non-zero) {
console.log(welcome + num)
}
which would compile into:
function test(welcome, num) {
if(Object.prototype.toString.call(welcome) !== "[object String]") {
throw new Error('welcome must be a string')
}
if (!Number.isInteger(num)) {
throw new Error('num must be an integer')
}
console.log(welcome + num)
}
What's the most straightforward way of doing this?
So far i've looked at:
sweet.js (online documentation looks out of date as I think it's going through some sort of internal rewrite)
esprima and escodegen (not sure where to start)
manually parsing using regular expressons
After evaluating all the various options, using sweet.js appears to be the best solution. It's still fairly difficult to get working (and I am probably doing stuff the wrong way) but just in case someone want's to do something similar this here was my solution.
'use strict'
syntax function = function(ctx) {
let funcName = ctx.next().value;
let funcParams = ctx.next().value;
let funcBody = ctx.next().value;
//produce the normal params array
var normalParams = produceNormalParams(funcParams)
//produce the checks
var paramChecks = produceParamChecks(funcParams)
//produce the original funcBody code
//put them together as the final result
var params = ctx.contextify(funcParams)
var paramsArray = []
for (let stx of params) {
paramsArray.push(stx)
}
var inner = #``
var innerStuff = ctx.contextify(funcBody)
for (let item of innerStuff) {
inner = inner.concat(#`${item}`)
}
var result = #`function ${funcName} ${normalParams} {
${paramChecks}
${inner}
}`
return result
function extractParamsAndParamChecks(paramsToken) {
var paramsContext = ctx.contextify(paramsToken)
//extracts the actual parameters
var paramsArray = []
var i = 0;
var firstItembyComma = true
for (let paramItem of paramsContext) {
if (firstItembyComma) {
paramsArray.push({
param: paramItem,
checks: []
})
firstItembyComma = false
}
if (paramItem.value.token.value === ',') {
firstItembyComma = true
i++
} else {
paramsArray[i].checks.push(paramItem.value.token.value)
}
}
for (var i = 0; i < paramsArray.length; i++) {
var checks = paramsArray[i].checks.join('').split(':')
checks.splice(0, 1)
paramsArray[i].checks = checks
}
return paramsArray
}
function produceNormalParams(paramsToken) {
var paramsArray = extractParamsAndParamChecks(paramsToken)
//Produces the final params #string
var inner = #``
var first = true
for (let item of paramsArray) {
if (first === true) {
inner = inner.concat(#`${item.param}`)
} else {
inner = inner.concat(#`,${item.param}`)
}
}
return #`(${inner})`
}
function produceParamChecks(paramsToken) {
var paramsArray = extractParamsAndParamChecks(paramsToken)
var result = #``
for (let paramObject of paramsArray) {
var tests = produceChecks(paramObject)
result = result.concat(#`${tests}`)
}
return result
}
function produceChecks(paramObject) {
var paramToken = paramObject.param
var itemType = paramObject.checks[0]
var checks = paramObject.checks
if (itemType === undefined) return #``
if (itemType === 'array') {
return #`if (Object.prototype.toString.call(${paramToken}) !== "[object Array]") throw new Error('Must be array:' + ${paramToken})`
else {
throw new Error('item type not recognised: ' + itemType)
}
}
}
I am trying to figure out a javascript function that will help resolve this test. I need to be able to determine if the string of words (var matches) that is given is an anagram of the word that I am running through (var subject). In this case there would not be a match. Any and all help will be greatly appreciated. Thank you in advance!
var anagram = require('./anagram');
describe('Anagram', function() {
it("no matches",function() {
var subject = anagram("diaper");
var matches = subject.matches([ "hello", "world", "zombies", "pants"]);
expect(matches).toEqual([]);
});
});
This is what I have so far:
for (var i = 0; i < matches.length; i++) {
if (subject.length != matches[i].length) {
return false
} else if (subject.length == matches[i].length){
var anagram = function(subject, matches) {
return subject.split("").sort("").join("") === matches[i].split("").sort("").join("");
};
}
Here is the fiddle:
http://jsfiddle.net/hn8r4v3u/2/
I alphabetized the letters within the word, as you were doing, in a function.
function getAlphaSortedWord(word) {
var baseWordCharArray = word.split("");
baseWordCharArray.sort();
return baseWordCharArray.join("");
}
The code has a set up:
var baseWord = getAlphaSortedWord("bob");
var thingsToCheck = ["obb", "2", "bob", "", "bo", "ob"];
And then solves it two ways, once with filter and once without it.
var matches = _.filter(thingsToCheck, function (str) {
return (baseWord === getAlphaSortedWord(str));
});
var matches2 = [];
for (index = 0; index < thingsToCheck.length; index++) {
if (baseWord === getAlphaSortedWord(thingsToCheck[index])) {
matches2.push(thingsToCheck[index]);
}
}
You should be able to use these to tie in with your real data for the test to pass.
NOTE, I would add some sanity for "is string" to my function if this is going to be production code.
Found here and it works: https://gist.github.com/AlbertoElias/10005056
function areAnagrams(a, b) {
var c = false;
if (a.length !== b.length) {
return c;
}
var hashMap = {};
var char;
var i;
for (i=0;i<a.length;i++) {
char = a[i];
hashMap[char] = hashMap[char] !== undefined ? hashMap[char]+1 : 1;
}
for (i=0;i<b.length;i++) {
char = b[i];
if (hashMap[char] !== undefined) {
if (hashMap[char] > 1) {
hashMap[char]--;
} else {
delete hashMap[char];
}
} else {
return c;
}
}
if (Object.keys(hashMap).length === 0) c = true;
return c;
}