Вот код, который выведет все совпадающие слова в обеих строках, если вы зарегистрируете слова1[я]. Я немного изменил код, чтобы проверить несоответствие слов, но безуспешно. предположим, что у нас есть две строки:
var str1 = "world is beautiful";
var str2 = "is world butiful";
Тогда вывод кода будет (на консоли):
(2) ["есть", "красиво"]
(2) ["мир", "красивый"]
Как мы можем регистрировать несоответствие слов между строками?
Вывод должен быть массивом результатов, например:
[красивая]
Вот что я пробовал:
var str1 = "world is beautiful";
var str2 = "is world bautiful";
var words1 = str1.split(/\s+/g),
myArray = str1.split(/\s+/g),
words2 = str2.split(/\s+/g),
i,
j;
for (i = 0; i < words1.length; i++) {
for (j = 0; j < words2.length; j++) {
if (words1[i].toLowerCase() == words2[j].toLowerCase()) {
output = myArray.filter( ( el ) => !words1[i].includes( el ) );
console.info(output);
}
}
}
Кажется, поскольку слова1[я] не является множество, весь код не работает.
Какие-либо предложения?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Извините, но перефразируя ваш вопрос, вы хотите создать два массива, один из совпадающих слов, а другой из не совпадающих слов.
Для оптимальной производительности вы можете создать своего рода хэш-карту со словами первой строки и посмотреть, есть ли слова второй строки в карте, и соответственно добавить в любой из массивов результатов.
Вы можете использовать простые объекты или карту в JavaScript, чтобы имитировать структуру хэш-карты. В приведенном ниже коде отображается только массив noMatchWords. Если вы хотите, чтобы и matchWords, и noMatchWords находились в одном и том же цикле, используйте метод reduce и вместо этого поместите слово в объект-аккумулятор с двумя массивами.
let str1= 'world is beautiful' , str2 = 'is world butiful';
wordMap = str1.split(' ').reduce((map,word) => { map[word.toLowerCase()] = true; return map; },{});
noMatchWords = str2.split(' ').filter(word => !wordMap[word.toLowerCase()]);
console.info(noMatchWords) // prints ['butiful'] since it is not in the first string. You can replace str1 and str2 in the steps 2 and 3 if you want to print words in str1 and not in str2 ie, get ['beautiful']
@ Сара Ри, но у меня let str1= 'I was' , str2 = 'I Was'; wordMap = str1.split(' ').reduce((map,word) => { map[word.toLowerCase()] = true; return map; },{}); noMatchWords = str2.split(' ').filter(word => !wordMap[word.toLowerCase()]); console.info(noMatchWords) работает, как и ожидалось
Чтобы разрешить одни и те же значения несколько раз в результате, вы можете использовать включает
let a = "sent erth protect it".split(' ');
let b = "sent to earth to protect it".split(' ');
let res = b.filter(i => !a.includes(i));
console.info(res);Или, как указал @Dhananjai Pai, создайте карта и используйте получить, чтобы проверить, имеет ли ключ значение true:
let map = new Map();
"sent erth protect it".split(' ').forEach(x => map.set(x, true));
let res = "sent to earth to protect it".split(' ').filter(x => !map.get(x));
console.info(res);Могу ли я включать повторяющиеся слова? скажем, если бы наши строки были var str1 = "отправлено, защитите это"; var str2 = "отправлен на землю, чтобы защитить ее"; мы хотели [на,землю,на], а не [на,землю] ???
@SaraRee Я добавил обновление к своему ответу, используя include.
Сложность здесь O(mn), где m — размер b, а n — размер a. Это тратит так много вычислений для поиска. Это можно сделать за O(m) другим методом. Для сравнения, если в каждой строке по 100 слов. Этот метод использует O (10000) сравнений, тогда как поиск требует только O (100).
@DhananjaiPai Я обновил свой ответ, используя карту. Спасибо что подметил это.
Произошло что-то проводное. если у меня есть это: пусть str1= 'Я был' , str2 = 'Я был'; несоответствующий вывод будет "I"