How to loop through string and check if there are unmatched letters - javascript

Currently I am looping through an array of letters, after each click a letter will be added. And there is also a string (var word) that will randomly be chosen, and the expected result is that it have to return true each time when there is an unmatching letter being added to the 'currentArray'. So after each click on an unmatched letter this function should still work!
For example if currentArray = ['b', 'o', 'l']
word is 'bob'. It should return true once....
I tried this one before, but as you might know this is the wrong way -->
currentArray.filter((word) => word !== word)

If I understand you correctly, the following code will help you.
let currentArray = ['b', 'o', 'l'];
let pattern = "bob";
let notIncluded = currentArray.filter(char => pattern.indexOf(char) === -1);
console.log(notIncluded);

Here's a one-liner that should do the trick.
const arr = ['b', 'o', 'l'];
const arr2 = ['b', 'o']
const word = 'bob';
let out = arr.filter(el => word.split('').indexOf(el) === -1).length > 0;
let out2 = arr2.filter(el => word.split('').indexOf(el) === -1).length > 0;
console.log(out, out2)
You're essentially filtering out elements of the array if a letter from the word is present, then check if the length is greater than 0.
I think this is what you were requesting.

Related

How to replace array element with respect to Index on another array

I have one array which contains values array1 = [a,b,c,d,e,f,g] and another array contains index of array1 and the value to be replaced array2 = [[2,u],[3,x],[6,z]].
Now I want to replace value of array1 with respect to array2 please not array2 consist of [array1_position, value_to_be_replaced]
Now my new arra1 should look like this array1 = [a,b,u,x,e,f,z].
I can do this with for loop but its again time consuming. what trick can i use to replace the value quickly. I am just learning about arrays and have a little knowledge on it.
I don't think there is any shorthand for such a verbose question.
Something on top of my mind is
array2.forEach((el) => {
array1[el[0]] = el[1];
})
you could do this
array2.forEach(arr => {
const [index, replaced] = arr;
array1[index] = replaced;
});
You can take fromEntries of the other array then just map it:
var array1 = ['a','b','c','d','e','f','g'];
var array2 = [[2,'u'],[3,'x'],[6,'z']];
var d=Object.fromEntries(array2);
var result = array1.map((val, i)=> d[i] || val);
console.log(result);
With an ordered array2 by indices, you could take a closure over an index of this array and map the values from eithe the first array or the replacements array.
var array1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g'],
array2 = [[2, 'u'], [3, 'x'], [6, 'z']],
result = array1.map(
(j => (v, i) => i === array2[j][0] ? array2[j++][1] : v)
(0)
);
console.log(result);

Javascript ordered array match with closest fallback

I've got a problem I'm trying to solve that I haven't quite been able to wrap my head around. If someone could point me in the right direction here, I'd appreciate it.
Basically, I'm comparing two ordered arrays in javascript. I have an index array and an array to match to. If all elements in the arrays match in order, I want to return a match. But, I also want to return the closest partial match. For instance
If my index array is
var index = ['A', 'B', 'C', 'D']
and the array I'm comparing is
var compare = ['A', 'B', 'C', 'D']
obviously the should match. But these should all match as well:
var compare = ['A']
var compare = ['A', 'B']
var compare = ['A', 'B', 'C']
These should not match:
var compare = ['B']; //doesn't start with 'A'
var compare = ['B', 'C']; //doesn't start with 'A'
var compare = ['B', 'A']; //not in correct order
The arrays will always be in the same order and the order must match in order to evaluate to true.
Basically, I'm trying to return most exact match that I can, but provide the closest fallback if that match doesn't exist. Does anybody know what I'm saying? Any help people could provide would be much appreciated
Just use Array.prototype.every and have the callback return true if the entries at the index for the two arrays match or if the index array has an entry for that index but the compare array doesn't:
const flag = index.every((entry, n) => compare.length <= n || compare[n] === index[n]);
or in ES5:
var flag = index.every(function(entry, n) {
return compare.length <= n || compare[n] === index[n];
});
Live example (ES2015+):
function test(index, compare, expect) {
const flag = index.every((entry, n) => compare.length <= n || compare[n] === index[n]);
console.log(index.join(","), compare.join(","), ":", flag, "=>", !flag === !expect ? "Good" : "ERROR");
}
const index = ['A', 'B', 'C', 'D'];
test(index, ['A', 'B', 'C', 'D'], true);
test(index, ['A'], true);
test(index, ['A', 'B'], true);
test(index, ['A', 'B', 'C'], true);
test(index, ['B'], false); //doesn't start with 'A'
test(index, ['B', 'C'], false); //doesn't start with 'A'
test(index, ['B', 'A'], false); //not in correct order
If as Titus suggests you have an array of arrays and want to find the best match, just loop through them and remember the longest one that matches:
let match = null;
for (const compare of arrayOfArraysToCompare) {
// No need to compare ones that are shorter than a known match...
if (!match || compare.length > match.length) {
const flag = index.every((entry, n) => compare.length <= n || compare[n] === index[n]);
if (flag && (!match || match.length < compare.length)) {
match = compare;
}
}
}
or in ES5
var match = null;
arrayOfArraysToCompare.forEach(function(compare) {
// No need to compare ones that are shorter than a known match...
if (!match || compare.length > match.length) {
var flag = index.every((entry, n) => compare.length <= n || compare[n] === index[n]);
if (flag && (!match || match.length < compare.length)) {
match = compare;
}
}
});
Live example (ES2015+):
const index = ['A', 'B', 'C', 'D'];
const arrayOfArraysToCompare = [
['A'], // Match, but not longest match
['A', 'B'], // *** Longest match
['B', 'C', 'D'] // Longer, but not a match
];
let match = null;
for (const compare of arrayOfArraysToCompare) {
// No need to compare ones that are shorter than a known match...
if (!match || compare.length > match.length) {
const flag = index.every((entry, n) => compare.length <= n || compare[n] === index[n]);
if (flag && (!match || match.length < compare.length)) {
match = compare;
}
}
}
console.log(match);
var index = ['A', 'B', 'C', 'D'];
var compare = ['A', 'B', 'C', 'D'];
function getMatches(array1, array2){
var matches = [];
array1.forEach((element, index) => {
if(element == array2[index])
matches.push(element);
else
return matches;
});
return matches;
}
getMatches(index, compare);

How can I split an array into two arrays with alternating elements

I want to split an array of strings into two arrays.
However, when I push the strings into the new arrays, it should be alternating. So, if the array is:
let alph = [a,b,c,d,e,f]
Then the new arrays would look like:
firstArr = [a,c,e]
secondArr = [b,d,f]
How can I do it so I'm not repeating myself? I have the following code, and it works, but I do not want to write two of the same filter functions (keep things DRY):
let firstArr = alph.filter((letter, index) => {
return index % 2 === 0;
})
You could take an array of the both arrays and take the index as indicator for the wanted array for pushing.
let alph = ['a', 'b', 'c', 'd', 'e', 'f'],
first = [],
second = [],
temp = [first, second];
alph.forEach((v, i) => temp[i % 2].push(v));
console.log(first);
console.log(second);
Since filter creates one array, you need two, or use e.g. forEach
var arr = ["a","b","c","d","e","f"], firstArr = [], secondArr = [];
arr.forEach( (a,i) => {
(i % 2 === 0) ? firstArr.push(a) : secondArr.push(a);
})
console.log(firstArr)
console.log(secondArr)
For better readability there's nothing wrong with having separate filter functions for these. To clean it up a little you could use arrow functions and make them 1 liners and then pass them in the filter function, like:
const alpha = ['a', 'b', 'c', 'd', 'e', 'f'];
const filterByEvens = (letter, index) => index % 2 === 0;
const filterByOdds = (letter, index) => index % 2 !== 0;
const evens = alpha.filter(filterByEvens);
const odds = alpha.filter(filterByOdds);
you can use reduce for this :
const alph = ['a', 'b', 'c', 'd', 'e', 'f'];
const result = alph.reduce((acc, letter, ndx) => {
acc[ndx % 2] = acc[ndx % 2] || [];
acc[ndx % 2].push(letter);
return acc;
}, []);
const [firstArr, secondArr] = result;
console.log(firstArr, secondArr);

Join array without removing whitespace

I have a little question about joining arrays. I have an array of letters, something like that:
let array = ['a','b','','c']
I wan't to join elements in array to have output like that:
let array = ['ab','c']
Can you help me? I was searching but everything i found was about removing whitespaces from arrays or string :(
Something along these lines:
let array = ['a', 'b', '', 'c'];
let res = array.reduce((res, s) => {
if (s.length) {
res[res.length - 1] += s;
} else {
res.push('');
}
return res;
}, ['']);
console.log(res);
It does make the assumption that there will be at least one string in the array, that the last element won't be an empty string and that there won't be two adjacent empty strings. Adjust as necessary if those are concerns.
You can use a combination of Array#map, Array#join and String#Split to achieve what you want.
Here, I used a space as the delimiter, but you can use anything that you don't use in your array.
let array = ['a','b','','c'];
let result = array.map(e => e.length ? e : ' ').join('').split(' ');
console.log(result);
You could use reduce() method to create new array and one variable to increment on empty string.
let array = ['a', 'b', '', 'c', 'd', 'e', '', '', '', 'f', '', 'g'];
let i = 0;
let result = array.reduce((r, e, j, arr) => {
r[i] = (r[i] || '') + e;
if (!e && arr[j - 1]) i++
return r;
}, [])
console.log(result)

Using slice() to extract segments of array not working

I have an array that contains 12 records. When i slice 4 elements from it. I shows me the sliced value, but when i slice the same array again it doesn't work for me.
var arraySliced = [a,b,c,d,e,f,g,h,i,j,k,h]
var Array1 = this.arraySliced.slice(0,4);
var Array2 = this.arraySliced.slice(4,4);
var Array3 = this.arraySliced.slice(8,4);
Array1 getting value:- a,b,c,d, but not getting value in array 2 and 3
You are assigning an object instead of array(as your requirement), I replaced array
Seccond you are using slice function incorrectly, the actual slice function defination is,
array.slice(start, end)
Try below code snippat ,
var arraySliced = ['a','b','c','d','e','f','g','h','i','j','k','h']
var Array1 = this.arraySliced.slice(0,4);
var Array2 = this.arraySliced.slice(5,7);
var Array3 = this.arraySliced.slice(8,11);
console.log(Array1);
console.log(Array2);
console.log(Array3);
slice(start_number, end_number)
var Array2 = this.arraySliced.slice(4,4);
=> Will not give any element because it doesn't get any number as per syntax.
If you want you can arraySliced.slice(4,5); will gives output ["e"]
arraySliced.slice(8,4)
=> Start number can't be greater than end number
The following function shows you what goes on when slicing up the array.
You need to state the block size and have the function figure out the number of blocks. The rest is just doing the slicing for you.
The underflow is just a safeguard, JavaScript does not care if your end index goes out of the array bounds.
var originalArray = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l' ];
var arraySlices = partitionArray(originalArray, 4);
console.log(arraySlices);
function partitionArray(arr, blockSize) {
var partitions = [],
numBlocks = Math.ceil(arr.length / blockSize),
underflow = numBlocks * blockSize - arr.length;
for (var index = 0; index < numBlocks; index++) {
var startIndex = index * blockSize,
endIndex = startIndex + blockSize - (index === numBlocks - 1 ? underflow : 0);
partitions.push(arr.slice(startIndex, endIndex));
}
return partitions;
}
.as-console-wrapper { top: 0; min-height: 100%; }
There are a couple of things you need to remember when using .slice().
As noted above, and in the docs: .slice(startNumber, endNumber)
Both of the parameters are optional.
REMEMBER start counting from Zero.
var Array0 = arraySliced(); // copies the entire array
var Array1 = arraySliced(0,4); // [a,b,c,d]
REMEMBER the endNumber tells JS where to stop counting BUT DOSEN'T include the endNumber element.
startNumber IS included in the resulting array.
So, your .slice(4,4), says to start counting at element index=4 (but the 5th element: e) and stop counting at the same element, but not include it, so basically this results in an empty array.
.slice(8,4) also results in the creation of an empty array.
Finally, if you want to count from the end of the array, use negative numbers:
.slice(-4); // [i,j,k,h]

Categories

Resources