Compare the 2nd strings characters with the 1st string in an array - javascript

I'm trying to figure out a challenge in Free Code Camp which states the following:
Return true if the string in the first element of the array contains all of the letters of the string in the second element of the array.
I understand how to do this if the 2nd string has a single character or if the 1st string has the 2nd string contained in the exact same sequence (e.g. "hello", "hel" and not "hello", "olleh"). But I can't figure out yet the correct approach to tackle this challenge.
Here is my code...
function mutation(arr) {
var myArray = arr.splice(1).toString().toLowerCase();
var splicedArray = arr.toString().toLowerCase();
if (splicedArray.search(myArray) != -1) {
return true;
} else {
return false;
}
}
Any combination which has a different sequence of the characters evaluates to false.
// e.g this is false
mutation(['Alien', 'line'])
What is the right way to complete this task?

Thanks to #Bergi I figured out the answer. Also he was so kind to allow me to post the answer myself. Here it is...
function mutation(arr) {
var string2 = arr.splice(1).toString().toLowerCase();
var string1 = arr.toString().toLowerCase();
for(var i = 0; i < string2.length; i++) {
if (string1.indexOf(string2.charAt(i)) == -1) {
return false;
}
}
return true;
}
If someone like me (JS beginner) encounters this task and finds this solution, here are some notable resources to read through if you do not know the methods used here..
.splice()
indexOf()
.slice()
Difference between .slice() and .splice() methods

You could also do this:
/**
* Match function that operates on a data array with two elements, where the
* first element is the query and the second element is the searchable data.
*
* Returns true if the query string contains all of the letters of the searchable
* data string.
*
* #param {Array} data - contains query and searchable string data
*
* #return {Boolean} if a match occured
*/
var match = function (data) {
// Convert strings to arrays.
var query = Array.prototype.slice.call(data[0]);
var searchableData = Array.prototype.slice.call(data[1]);
// Every query string character should occur in the searchable data.
return query.every(function (search) {
// Only some of the searchable data characters should occur in the query data.
return searchableData.some(function (target) {
return search === target;
});
});
};
match([ 'abc', 'xyzadefbhijc' ]); // returns true
match([ 'abq', 'xyzadefbhijc' ]); // returns false

My mutation
function mutation(arr) {
var string2 = arr[1].toLowerCase();
var string1 = arr[0].toLowerCase();
for(var i = 0; i < string2.length; i++) {
if (string1.indexOf(string2.charAt(i)) == -1) {
return false;
}
}
return true;
}

The same can be done using map:
function mutation(arr) {
var one = arr[0].toLowerCase();
var two = arr[1].toLowerCase().split('');
var match = true;
two.map(function(val){
if(one.indexOf(val) === -1){
match = false;
}
});
return match;
}

function mutation(arr) {
var src=arr[0].toLowerCase();
var dist=arr[1].toLowerCase();
for(var i=0;i<dist.length;i++){
if(src.indexOf(dist[i])<0) return false;
}
return true;
}
console.log(mutation(["voonoo", "no"]))

Related

How to check if user input includes all of needed information in random order?

I have a task and I need a function that validate '123456' equals '213456','312456' etc. Maybe, I missing something, but absolutely have no idea how to validate it
I tried to do regexp like if(userInput = [/answer/g] return true but it isn't work
The following checks that one string is a permutation of another as long as all the characters in the set string are different.
let s = new Set('123456');
let input = '213456';
if(input.length === s.size && [...input].every(c => s.has(c)))
return true;
let string = '123457';
let user_input ='623451';
function compare(string, user_input)
{
if(string.length == user_input.length)
{
for (let i = 0; i < string.length; i++) {
if (user_input.includes(string[i])) continue;
else
return false;
}
return true;
}
else
{
console.log('failure');
}
}
console.log(compare(string, user_input));
you might like this solution
Here a solution which runs in O(n) and can also be used if the expected string contains duplicate charaters like e.g. 112233 (see second example within the code), which other solutions posted here are not taking into consideration.
The idea here is that you first create a lookup table (I am using a JavaScript object here) once which holds all the numbers/ characters and their count within the expected word. Then using this lookup table I check for any of the characters in a user supplied word (the word which has to be validated) if it has all the expected characters and (this is the distinction to other answers posted here) if their count matches the expected count of said character/ number. If one string is a permutation of the other the lookup table should have 0 as the count for every single character. If any character is not 0, it is not a permutation.
function validate(userInput, validOptionsMap) {
// create a copy as we are mutating the values within the object
const validOptionsWithCount = { ...validOptionsMap
};
const elementsMatch = userInput.split("").every(input => {
if (validOptionsWithCount[input]) {
const count = validOptionsWithCount[input];
if (count === 0) {
return false;
}
validOptionsWithCount[input] = count - 1;
return true;
}
return false;
});
if (!elementsMatch) return false;
return Object.values(validOptionsWithCount).every(count => count === 0);
};
function buildLookupTableForExpectedPermutation(expectedPalindrome) {
return expectedPalindrome.split("")
.reduce((all, cur) => (all[cur] ?
all[cur] = all[cur] + 1 :
all[cur] = 1, all), {});
}
// Your example
const permutation = "123456";
const validOptionsWithCount = buildLookupTableForExpectedPermutation(permutation);
console.log(`Checking for permutations of ${permutation}`)
console.log("123456:", validate("123456", validOptionsWithCount)); // true
console.log("123457:", validate("123457", validOptionsWithCount)); // false
console.log("265413:", validate("265413", validOptionsWithCount)); // true
console.log("2654131:", validate("2654131", validOptionsWithCount)); // false
console.log("261413:", validate("261413", validOptionsWithCount)); // false
// example with multiple identical values (other solutions posted here will fail at least one of these tests)
const permutation2 = "112233";
const validOptionsWithCount2 = buildLookupTableForExpectedPermutation(permutation2);
console.log(`Checking for permutations of ${permutation2}`)
console.log("112233:", validate("112233", validOptionsWithCount2)); // true
console.log("123123:", validate("123123", validOptionsWithCount2)); // true
console.log("123131:", validate("123131", validOptionsWithCount2)); // false
console.log("1231231:", validate("1231231", validOptionsWithCount2)); // false
console.log("12312:", validate("12312", validOptionsWithCount2)); // false

How to compare the values in a list and the value that is compared to will be inserted to the front or back if its larger or smaller?

I am creating a function that inserts an element into a list only if the element to be inserted
is larger than any of the elements currently in the list. Larger can mean either greater
than when working with numeric values, or further down in the alphabet, when
working with textual values.
var names = new List();
function List(){
this.dataStore = [];
this.listSize = 0;
this.pos = 0;
this.append = append;
}
function append(element){
for (i = 0; i > this.dataStore.value;++i){
if (names.value == this.dataStore[i].value){
this.dataStore[this.listSize++] = element;
this.pos++;
}
}
}
function insert(element, after) {
var insertPos = this.find(after);
if (insertPos > -1) {
this.dataStore.splice(insertPos+1, 0, element);
++this.listSize;
return true;
}
return false;
}
function find(element){
for (var i = 0; i < this.dataStore.length;++i){
if(this.dataStore[i]== element){
return i;
}
}
return -1;
}
names.append("Jascien");
console.log(names);
names.append("Jas");// i want to insert this value after its compared to the exiting values in the front of the first value or after it.
console.log(names);
names.append("John"); // also this one
console.log(names);
By numeric values you mean number as string, or number as Number. If number as Number, then I think it would be good to divide this condition check in two separate condition check, depending on type of data entered as element.
As written above, please provide some input and output arrays for better understanding what you expect from this function.

Compare each element of one array to another and find which element is not found

I have two array which contains special characters am trying to compare each element of one array to another and get the element which is not found in another array. But my approach doesnt work properly
var specialChar = ['!','#','#','$','%','&'];
var $scope.inp= ['!','*','#'];
In my above example element '*' is not present specialChar
I tried this logic -
$scope.validateChar = function(specialChar,inp){
var i,j;
for (i=0,j=0; i<specialChar.length && j<inp.length;) {
if (specialChar[i] < inp[j]) {
++i;
} else if (specialChar[i] == inp[j]) {
++i; ++j;
} else {
$scope.notFoundChar = inp[j];
Error prompt showing special charatcter $scope.notFoundChar not found
$scope.charAllowedText = false;
return;
}
}
}
Please suggest what am doing wrong here?
You can filter out your Special char '*' like below
var result=[]
inp.map(function(inpElement){
if(specialChar.indexOf(inpElement)==-1)
result.push(inpElement)
})
console.log(result)
Below given code solves your problem.
var source = [1,2,3,4,5,6,7,8];
var target =[2,3,4,5,6,18,19];
var missingItems = [];
target.forEach(function(itemFromTarget){
var itemFound = false;
source.forEach(function(itemFromSrc){
if(itemFromTarget === itemFromSrc){
itemFound = true;
}
});
if (!itemFound) {
missingItems.push(itemFromTarget);
}
});
console.log(missingItems);

loop through array to find matches and return every possible solution

I have a small input field where this code gets activated everytime a key is pressed inside it. But it now only prints "found something" when the name exacly matches what you type in the input field.
How can change a part that when I type something like "b" it already removes the matches where there is no "b" in the name is and print every possible matches that still have a "b".
My small code to find the match.
Info is my json big array where I can loop through all the names with info[i].name
var textInput = $findperson.find('input').val();
console.log(textInput);
for (i = 1; i < info.length; i++) {
if (textInput === info[i].name) {
console.log('found something');
}
}
Set Flag if found any match and print them, otherwise print found nothing,
for gi g mean search globally and i mean ignore case sothat A will match a and vise verse.
var textInput = $findperson.find('input').val();
console.log(textInput);
found = false
for (i = 1; i < info.length; i++) {
if (info[i].name.match(new RegExp(textInput,"gi")) ) {
console.log(info[i].name);
found = true
}
}
if(!found){
console.log("found nothing")
}
I would use regex like this:
var textInput = $findperson.find('input').val();
var regex = new Regexp(".*("+textInput+").*","i");
var filtered = info.filter(function (current) {
return current.name.match(regex);
});
console.log(filtered);
Just use indexOf to search for one String within another:
if(info[i].name.indexOf(textInput) != -1) {
indexOf will return -1 if String isn't found within the other.
You can try searching for some letters in one of the results 'balloon', 'ball', 'apple' in the example below:
var results = ['balloon', 'ball', 'apple'];
function filterResults() {
var input = document.getElementById('input').value;
var resultsFiltered = results.filter(function(a) {
return a.indexOf(input) != -1;
});
var result = ''; resultsFiltered.map(function(a) {
result += a + '<br/>';
}); document.getElementById('result').innerHTML = result;
}
<input id='input' onkeyup='filterResults();'/>
<div id='result'></div>

Finding multiple values in a string Jquery / Javascript

I have a three strings of categories
"SharePoint,Azure,IT";
"BizTalk,Finance";
"SharePoint,Finance";
I need to find a way to check if a string contains for example "SharePoint" and "IT", or "BizTalk" and "Finance". The tests are individual strings themselces.
How would i loop through all the category strings (1 - 3) and only return the ones which have ALL instances of the souce.
i have tried the following
function doesExist(source, filterArray)
{
var substr = filterArray.split(" ");
jQuery.each(substr, function() {
var filterTest = this;
if(source.indexOf(filterTest) != -1 )
{
alert("true");
return true;
}else
{
alert("false");
return false;
}
});
}
with little success...the code above checks one at a time rather than both so the results returned are incorrect. Any help would be great.
Thanks
Chris
UPDATE: here is a link to a work in progress version..http://www.invisiblewebdesign.co.uk/temp/filter/#
Try this:
function doesExist(source, filter)
{
var sourceArray = source.split(",");
var filterArray = filter.split(",");
var match = true;
$.each(filterArray, function(i, val) {
match = match && ($.inArray(val, sourceArray) != -1);
});
return match;
}
gives doesExist("SharePoint,Azure,IT", "SharePoint,IT")==true but doesExist("SharePoint,Azure,IT", "SharePoint,BizTalk")==false.
you could try something like:
if(filterArray.indexOf("SharePoint") > -1 && filterArray.indexOf("IT") > -1) {
...
}

Categories

Resources