How to iterate through two array and compare their elements - javascript

I want to compare each element of two arrays.
Person writes down something in input. I want to compare what person had written with another phrase. The idea I took from this site https://lingua.com/german/dictation/ , you can check to understand what i want. It is kind of dictation, person writes down something and at the end he can check mistakes and so on.
I tried to realize function with two different ways, but it does not work
let [value, setValue] = useState("currentValue")
let [correctText, setCorrectText] = useState("Every day I work hard to achive my goals")
let [answer, setAnswer] = useState<string[]>([])
// first variant
let compare = () => {
let correctTextValue = correctText.split(" ")
let valueArray = value.split(" ")
let arr = []
for (let i=0; i<correctTextValue.length; i++) {
for (let j=0; j<valueArray.length; j++) {
if (correctTextValue[i]===valueArray[j]) {
arr.push(valueArray[j])
}
else {
arr.push(correctTextValue[j]
}
}
}
setAnswer([...answer, ...arr])
}
//second variant
let compare = () => {
let correctTextValue = correctText.split(" ")
let valueArray = value.split(" ")
let arr = []
for (let i=0; i<correctTextValue.length; i++) {
for (let j=0; j<valueArray.length; j++) {
if (correctTextValue[i]===valueArray[j]) {
setAnswer([...answer, valueArray[j]])
}
else {
setAnswer([...answer, correctTextValue[j]])
}
}
}
}
// this is simple jsx code
<input value={value} onChange={e=>setValue(e.target.value)}/>
<button onClick={() => compare()}>Submit</button>
<div>{answer.map(el=><span> {el} </span>)}</div>

Here's an updated version of your code that should work (if I understood correctly). It compares the words from correctText and value word by word and marks different words as isCorrect: false. It then uses that information inside the JSX to add underline styles to incorrect words.
let [value, setValue] = useState("")
let [correctText, setCorrectText] = useState("Every day I work hard to achive my goals")
let [answer, setAnswer] = useState([])
let compare = () => {
let correctTextValue = correctText.split(" ")
let valueArray = value.split(" ")
let arr = correctTextValue.map((word, index) => {
if (word === valueArray[i]) {
return {
isCorrect: true,
word: word
};
}
return {
isCorrect: false,
word: valueArray[i]
};
});
setAnswer(arr);
}
<input value={value} onChange={e=>setValue(e.target.value)}/>
<button onClick={() => compare()}>Submit</button>
<div>{
answer.map(el => {
return el.isCorrect
? <span>el.word</span>
: <span style="text-decoration:underline">el.word</span>
})
}</div>

t.fail = () => {throw Error("Unit test failed.")};
t.seqsUnequal = (a, b) => {
/* if (a === b) return false; */
let value, done;
const b_iter = b[Symbol.iterator]();
for (const a_elt of a) {
({value, done} = b_iter.next());
if (done) return "b short";
if (value !== a_elt)
return `different values ${typeof value}:${typeof a_elt}`;
};
({value, done} = b_iter.next());
if (! done) return "a short";
return false
};
t.seqsEqual = (a, b) => ! t.seqsUnequal(a, b);
t.exp_seq_0 = ["Greens"];
if (! t.seqsEqual(t.exp_seq_0, t.exp_seq_0)) t.fail();
if (! t.seqsEqual([], [])) t.fail();
if (t.seqsEqual(["foo"], [])) t.fail();
if (t.seqsEqual([], [0])) t.fail();
if (! t.seqsEqual(["fox", "went", "out", "on", "a", "winter's", "night"]
, ["fox", "went", "out", "on", "a", "winter's", "night"])) t.fail();
The above code will shallow-compare any two iterables for equality. But given that you know that you have arrays, you can use indexing, for a much simpler solution.

Related

Array of functions with condition

I am currently working on an array of functions and want to get the right function back with a condition.
Here is my code :
{'key':'a', 'function':func_a},
{'key':'b', 'function':func_b},
{'key':'c', 'function':func_c},
{'key':'d', 'function':func_d}
];
const term = 'b';
const funcToDo = for (var i = 0; i < array.length; i++) {
if (term === a[i].key) {
return a[i].function
}
}
const shouldIDoIt = true;
shouldIDoIt === true ? functToDo() : null;
Can someone help me on this ?
Use Array.prototype.find to then return from that array an Object which matches a specific property value
const find = (arr, k, v) => arr.find(ob => ob[k] === v);
const func_a = () => console.log("aaa!");
const func_b = () => console.log("bbb!");
const func_c = () => console.log("ccc!");
const arrFn = [
{key: "a", function: func_a},
{key: "b", function: func_b},
{key: "c", function: func_c},
];
const funcToDo = find(arrFn, "key", "b")?.function;
const shouldIDoIt = true;
funcToDo && shouldIDoIt && funcToDo();

Recursive function on sorted array returns undefined

I'm attempting to solve this problem recursively: Clean the room function: given an input of [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20], make a function that organizes these into individual array that is ordered. For example answer(ArrayFromAbove) should return: [[1,1,1,1],[2,2,2], 4,5,10,[20,20], 391, 392,591]
Array:
const array1 = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
array1.sort((a,b) => a-b);
Main Function:
const sortArray = (mainArr) => {
let acc = [];
console.log(acc, "acc");
const recursive = (arr) => {
if (arr.length > 1) {
console.log("inside func2 ", acc);
let likeArr = singArr(arr, arr[0]);
console.log(likeArr, "like");
arr = deleteVal(arr, arr[0]);
acc.push(likeArr);
return recursive(mainArr);
}
else {
return acc;
}
}
};
Helper Functions:
const singArr = (arr1, val) => {
let returnVal = arr1.filter(num => num === val);
return (returnVal.length === 1 ? returnVal[0] : returnVal);
};
const deleteVal = (arr, val) => {
let returnVal = arr.filter(num => num !== val);
return returnVal
};
Idea is to go through the array that I've sorted, filter using the first item in the array to get back a new array (single value if there's only one) with the like items, push it to my accumulator and then delete every instance of it in the original array.
I'm trying to do this recursively until there are no items left in the original array but it's returning undefined.
Any ideas where I'm going wrong?
inside your recursive function you are doing
return recursive(mainArr);
instead try to return recursive(arr);
You're not calling the recursive function from outside of the function.
const sortArray = (mainArr) => {
let acc = [];
console.log(acc, "acc");
const recursive = (arr) => {
if (arr.length > 1) {
console.log("inside func2 ", acc);
let likeArr = singArr(arr, arr[0]);
console.log(likeArr, "like");
arr = deleteVal(arr, arr[0]);
acc.push(likeArr);
return recursive(mainArr);
}
else {
return acc;
}
}
return recursive(mainArr)
};
Also, I believe the code posted doesn't return the desired output. You can probably do the following:
const array1 = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
array1.sort((a,b) => a-b);
const map = new Map();
array1.forEach((item) => {
if(map.has(item)) {
const storedItem = map.get(item);
map.set(item, Array.isArray(storedItem) ? [...storedItem, item] : [storedItem, item])
} else {
map.set(item, item);
}
});
console.log(Array.from(map.values()))
You never call the function recursive.
const sortArray = (mainArr) => {
let acc = [];
console.log(acc, "acc");
const recursive = (arr) => {
if (arr.length > 1) {
console.log("inside func2 ", acc);
let likeArr = singArr(arr, arr[0]);
console.log(likeArr, "like");
arr = deleteVal(arr, arr[0]);
acc.push(likeArr);
return recursive(mainArr);
}
else {
return acc;
}
}
recursive(mainArr) //<--- Call it!
};
You will also notice that sortArray does not return anything, so you may want to change recursive(mainArr) to return recursive(mainArr) to get a return.
Of note, the code does not produce the desired result, but this fix should get you going.

arranging words in an alphabetical order

I have a question, I have a text.file that contains a string, this code right now prints out words and lets me know how many same words have been used..
Is there a way that I could put the words in an alphabetical order in the Node.js environment.
Code:
const { readFile, readFileSync } = require('fs');
let file = 'C:\\Users\\eeroj\\source\\repos\\Nodejs\\pish\\pish\\TextFile2.txt';
let words = "";
function countRepeatedWords(sentence) {
let words = sentence.split(" ");
let wordMap = {};
for (let i = 0; i < words.length; i++) {
let currentWordCount = wordMap[words[i]];
let count = currentWordCount ? currentWordCount : 0;
wordMap[words[i]] = count + 1;
}
return wordMap;
}
words = readFileSync(file).toString();
console.log(countRepeatedWords(words));
You can use Object.entries() to create a list of your object entries, then sort them by key using Array.sort(), then create your sorted map using Object.fromEntries():
const { readFileSync } = require('fs');
let file = 'C:\\Users\\eeroj\\source\\repos\\Nodejs\\pish\\pish\\TextFile2.txt';
function countRepeatedWords(sentence) {
const wordMap = sentence.toLowerCase().split(" ").reduce((acc,cur) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc;
}, {});
// Sort the map alphabetically...
const sortedEntries = Object.entries(wordMap).sort(([a,],[b,]) => a.localeCompare(b));
const sortedWordMap = Object.fromEntries(sortedEntries);
return sortedWordMap;
}
const words = readFileSync(file).toString();
console.log(countRepeatedWords(words));
And a snippet to demonstrate:
function countRepeatedWords(sentence) {
const wordMap = sentence.toLowerCase().split(" ").reduce((acc,cur) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc;
}, {});
// Sort the map alphabetically...
const sortedEntries = Object.entries(wordMap).sort(([a,],[b,]) => a.localeCompare(b));
const sortedWordMap = Object.fromEntries(sortedEntries);
return sortedWordMap;
}
const words = `What a piece of work is a man How Noble in reason How infinite in faculty In form and moving how express and admirable In Action how like an Angel in apprehension how like a God The beauty of the world the paragon of animals and yet to me what is this quintessence of dust Man delights not me nor woman neither though by your smiling you seem to say so` ;
console.log(countRepeatedWords(words));
Your data is wordMap = [{'word':'A'},{'word':'B'}, ...]
wordMap.sort((a,b) => a.word - b.word);
Your data is wordMap = [A', 'B', ...]
wordMap.sort();

Script to group elements where every character is same to each other

For input:
["abc","def","okg","fed","bca"]
expected output should be:
["abc","bca"],["def","fed"],["okg"]
here "abc", "bca" and "def", "fed" contains same character and "okg" there is no element which contains these character
const arr = ["abc", "def", "okg", "fed", "bca"];
let find = (arr) => {
let res = [];
for (let i = 0; i < arr.length; i++) {
for (let j = 1; j < arr.length; j++) {
if (arr[i].search(arr[j])) {
res.push(arr[j]);
}
}
}
return res;
}
console.log(find(arr))
A reduce will do the trick - it seems the shortest code here (apart from the one using lodash)
const arr = ["abc", "def", "okg", "fed", "bca"],
res = Object.values(arr.reduce((acc, ele) => {
const key = ele.split("").sort();
(acc[key] = acc[key] || []).push(ele)
return acc
}, {}))
console.log(res)
.search returns a number indicating the index of where the match was found. Check that the result isn't -1 instead of checking that the result is truthy. But...
.search isn't the right tool here anyway, because it won't find different combinations of the same character. You need a different approach. One way would be to create an object whose keys are the characters found, and the values are the number of occurrences, then use a sorted representation of that object as a key. For example, have both abc and bca turn into something like:
a,1-b,1-c,1
Iterate through the input array, generating a key for each string, and putting the string on an object with that key. At the end, take the object's values.
const strToKey = (str) => {
const grouped = {};
for (const char of str) {
grouped[char] = (grouped[char] || 0) + 1;
}
return Object.entries(grouped)
.sort((a, b) => a[0].localeCompare(b[0]))
.join('-');
};
let find = (arr) => {
const grouped = {};
for (const str of arr) {
const key = strToKey(str);
grouped[key] ??= [];
grouped[key].push(str);
}
return Object.values(grouped);
}
console.log(find(["abc", "def", "okg", "fed", "bca"]));
Another option, when creating the keys, instead of sorting the object afterwards, you could sort the string first:
const strToKey = (str) => {
const grouped = {};
for (const char of [...str].sort()) {
grouped[char] = (grouped[char] || 0) + 1;
}
return Object.entries(grouped).join('-');
};
let find = (arr) => {
const grouped = {};
for (const str of arr) {
const key = strToKey(str);
grouped[key] ??= [];
grouped[key].push(str);
}
return Object.values(grouped);
}
console.log(find(["abc", "def", "okg", "fed", "bca"]));
const input = ["abc","def","okg","fed","bca"]
function getSortedString (str) {
return [...str].sort().join('');
};
function groupBy(input) {
const grouped = [];
while(input.length) {
const nextInput = [];
const first = input[0];
const matched = [first];
for (let i = 1; i < input.length; i++) {
if(getSortedString(first) === getSortedString(input[i])) {
matched.push(input[i])
} else {
nextInput.push(input[i])
}
}
input = nextInput;
grouped.push(matched);
}
console.log(grouped);
}
groupBy(input);
Using Object.values and groupBy (from lodash), you can get a straightforward solution:
You group your array elements by their "sorted" form and then use Object.values to get the output array.
const arr = ["abc", "def", "okg", "fed", "bca"];
const sortString = (str) => str.split("").sort().join("")
const result = Object.values(_.groupBy(arr, sortString));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

strings from array contain common substring javascript

Here is my code:
I want to iterate through each pair of elements of the arrays, and if the strings in each pair contain one or more common substrings, console.log(true), otherwise console.log(false).
So, output should be true, false, because "first" and "criss" have common substrings ("r", "i", "s")
Here is my code for now;
const a = ["first", "hi"];
const b = ["criss", "student"];
function commonSubstring(a, b) {
a.forEach(a1 =>
b.forEach(a2 => {
for (i = 0; i < a1.length; i++) {
if (a1.charAt(i) == a2.charAt(i)) {
console.log(true");
}
}
})
);
}
commonSubstring(a, b);
Thanks for answers in advance!
You could take a Set and check if a character is common.
function common(a, b) {
return [...a].some(Set.prototype.has, new Set(b));
}
var a = ["first", "hi"],
b = ["criss", "student"],
result = a.map((v, i) => common(v, b[i]));
console.log(result);
const a = ["first", "hi"];
const b = ["criss", "student"];
function commonSubstring(a, b) {
let result = [];
a.forEach(a1 => {
let found = false;
b.forEach(a2 => {
for (i = 0; i < a1.length; i++) {
if (a1.charAt(i) == a2.charAt(i)) {
//console.log(true);
found = true;
}
}
})
result.push(found);
//console.log(found)
});
return result.join(',');
}
console.log(commonSubstring(a, b));

Categories

Resources