Как в javascript найти одинаковые строки

There are multiple methods available to check if an array contains duplicate values in JavaScript. You can use the indexOf() method, the Set object, or iteration to identify repeated items in an array.

Set Object

Set is a special data structure introduced in ES6 that stores a collection of unique values. Since each value in a Set has to be unique, passing any duplicate item will be removed automatically:

const numbers = [1, 2, 3, 2, 4, 5, 5, 6];

const unique = Array.from(new Set(numbers));

console.log(unique);
// [ 1, 2, 3, 4, 5, 6 ]

The Array.from() method, we used above, converts the Set back to an array. This is required because a Set is not an array. You could also use spread operator if you want for conversion:

const unique = [...new Set(numbers)];

To check if there were duplicate items in the original array, just compare the length of both arrays:

const numbers = [1, 2, 3, 2, 4, 5, 5, 6];

const unique = Array.from(new Set(numbers));

if(numbers.length === unique.length) {
    console.log(`Array doesn't contain duplicates.`);
} else {
    console.log(`Array contains duplicates.`);
}
// Output: Array contains duplicates.

To find out exactly which elements are duplicates, you could make use of the unique array above, and remove each item from the original array as shown below:

const numbers = [1, 2, 3, 2, 4, 5, 5, 6];

const set = new Set(numbers);

const duplicates = numbers.filter(item => {
    if (set.has(item)) {
        set.delete(item);
    } else {
        return item;
    }
});

console.log(duplicates);
// [ 2, 5 ]

indexOf() Method

In this method, we compare the index of the first occurrence of an element with all the elements in an array. If they do not match, it implies that the element is a duplicate:

const numbers = [1, 2, 3, 2, 4, 5, 5, 6];

const duplicates = numbers.filter((item, index) => index !== numbers.indexOf(item));

console.log(duplicates);
// [ 2, 5 ]

The above solution works perfectly as long as you only want to check if the array contains repeated items. However, the output array may contain duplicate items if those items occur more than twice in the array:

const numbers = [1, 2, 3, 2, 2, 4, 5, 5, 6];

const duplicates = numbers.filter((item, index) => index !== numbers.indexOf(item));

console.log(duplicates);
// [ 2, 2, 5 ]

some() Method

In JavaScript, the some() method returns true if one or more elements pass a certain condition.

Just like the filter() method, the some() method iterates over all elements in an array to evaluate the given condition.

In the callback function, we again use the indexOf() method to compare the current element index with other elements in the array. If both the indexes are the same, it means that the current item is not duplicate:

const numbers = [1, 2, 3, 2, 4, 5, 5, 6];

const isDuplicate = numbers.some((item, index) => index !== numbers.indexOf(item));

if (!isDuplicate) {
    console.log(`Array doesn't contain duplicates.`);
} else {
    console.log(`Array contains duplicates.`);
}
// Output: Array contains duplicates.

for Loop

Finally, the last method to find duplicates in an array is to use the for loop.

Here is an example that compares each element of the array with all other elements of the array to check if two values are the same using nested for loop:

const numbers = [1, 2, 3, 2, 4, 5, 5, 6];

let isDuplicate = false;

// Outer for loop
for (let i = 0; i < numbers.length; i++) {
    // Inner for loop
    for (let j = 0; j < numbers.length; j++) {
        // Skip self comparison
        if (i !== j) {
            // Check for duplicate
            if (numbers[i] === numbers[j]) {
                isDuplicate = true;
                // Terminate inner loop
                break;
            }
        }
        // Terminate outer loop
        if (isDuplicate) {
            break;
        }
    }
}

if (!isDuplicate) {
    console.log(`Array doesn't contain duplicates.`);
} else {
    console.log(`Array contains duplicates.`);
}
// Output: Array contains duplicates.

✌️ Like this article? Follow me on
Twitter
and LinkedIn.
You can also subscribe to
RSS Feed.

Есть более простое (алгоритмически) решение.
Общая суть его такова, вместо построения матрицы N1 x N2 делаем последовательный сдвиг меньшей строки относительно большей (1 цикл длинной N1+N2-2). На каждой итерации этого сдвига делаем второй цикл через текущую область пересечения этих строк, подсчитывая совпадения символов и запоминая их, если число совпадений больше предыдущего. Так же время выполнения такого алгоритма будет не O(Nmax*Nmin) а O(Nmax*Nmin -Nmin)

Если не поленюсь, оформлю с утра в виде кода)

PS: Заставляете не полениться:) Для поддержки поиска по строкам в количестве больше 2-х алгоритм был несколько модифицирован. Для удобства понимания почти не использовал “особые фишки” JavaScript-а, все выполнено на обычных циклах.

код с комментариями

function search_largest_substr(){
	/*
	Наибольшая общая строка не может 
	быть больше наименьшей входной строки.
	Находим наименьшую и по ходу формируем
	массив с остальными:
	*/

		// в эту переменную внесем самую маленькую подстроку
		let str_min = arguments[0];
		// сюда сложим все остальные подстроки
		const list = [];
		
		// пробежим в цикле по всем переданным в функцию аргументам
		for(let n=1; n<arguments.length; n++){
			// если строка в str_min меньше чем в
			if(str_min.length<arguments[n].length){
				// вносим в list текущую строку
				list.push(arguments[n]);
				// переходим к следующей итерации цикла
				continue;
			}

			// иначе в list строку, лежащую в str_min
			list.push(str_min);
			// запоминаем в str_min текущую строку
			str_min = arguments[n];
		}

	/*
	Далее нам надо проверить наличие всех возможных
	подстрок из самой маленькой строки в других строках.
	Например если самая маленькая подствока была "abcd"
	то надо последовательно проверить 
	"abcd", "abc", "bcd", "ab", "bc", "cd", "a", "b", "c", "d"
	Но при этом, как только будет найдена подстрока имеющаяся
	во всех строках надо сразу завершить цикл с проверкой.
	*/
		// Данный цикл будет определять текущий размер 
		// проверяемой подстроки, начиная от наибольшего возможного.
		// Например для строки "abcd" это будут значения 4, 3, 2, 1
		for(let l=str_min.length; l>0; l--){

			// В данном цикле определяем позицию подстроки.
			// Например для строки "abcd" это будут значения:
			// при l=4 будут 0
			// при l=3 будут 0, 1
			// при l=2 будут 0, 1, 2
			// при l=1 будут 0, 1, 2, 3
			for(let p=0; p<=str_min.length-l; p++){
				// берем из наименьшей строки тестируемую подстроку
				const substr = str_min.slice(p, p+l);

				// если искомый фрагмент есть во всех строках
				// то isFound будет присвоено true
				let isFound = true;

				// далее в цикле проверяем все остальные строки 
				// на наличие искомой подстроки
				for(let i=0; i<list.length; i++){
					// если искомая подстрока присутствует в
					// текущей строке - ничего не делаем
					if(	list[i].indexOf(substr) >= 0)
						continue;

					// иначе выставляем isFound=false 
					// и прерываем текущий цикл по i
					isFound=false;
					break;
				}

				// если isFound == true значит нужная подстрока найдена
				if( isFound )
					return substr;

				// иначе продолжаем поиск
			}
		}

		// если не было найдено ни единой соврадающей подстроки
		// возвращаем пустую строку
		return "";
}


// Исползуем функцию поиска так:
var str = search_largest_substr("ABCDEFGH", "ABCDEFG", "ABCDEF");
console.log(str);


str = search_largest_substr("123445", "12654", "123768");
console.log(str);

Another approach (also for object/array elements within the array1) could be2:

function chkDuplicates(arr,justCheck){
  var len = arr.length, tmp = {}, arrtmp = arr.slice(), dupes = [];
  arrtmp.sort();
  while(len--){
   var val = arrtmp[len];
   if (/nul|nan|infini/i.test(String(val))){
     val = String(val);
    }
    if (tmp[JSON.stringify(val)]){
       if (justCheck) {return true;}
       dupes.push(val);
    }
    tmp[JSON.stringify(val)] = true;
  }
  return justCheck ? false : dupes.length ? dupes : null;
}
//usages
chkDuplicates([1,2,3,4,5],true);                           //=> false
chkDuplicates([1,2,3,4,5,9,10,5,1,2],true);                //=> true
chkDuplicates([{a:1,b:2},1,2,3,4,{a:1,b:2},[1,2,3]],true); //=> true
chkDuplicates([null,1,2,3,4,{a:1,b:2},NaN],true);          //=> false
chkDuplicates([1,2,3,4,5,1,2]);                            //=> [1,2]
chkDuplicates([1,2,3,4,5]);                                //=> null

See also…

1 needs a browser that supports JSON, or a JSON library if not.
2 edit: function can now be used for simple check or to return an array of duplicate values

В этом посте мы обсудим, как найти все дубликаты в массиве в JavaScript.

1. Использование Array.prototype.indexOf() функция

Идея состоит в том, чтобы сравнить индекс всех элементов в массиве с индексом их первого появления. Если оба индекса не совпадают ни для одного элемента в массиве, можно сказать, что текущий элемент дублируется. Чтобы вернуть новый массив с дубликатами, используйте filter() метод.

В следующем примере кода показано, как реализовать это с помощью indexOf() метод:

const arr = [ 5, 3, 4, 2, 3, 7, 5, 6 ];

const findDuplicates = arr => arr.filter((item, index) => arr.indexOf(item) !== index)

const duplicates = findDuplicates(arr);

console.log(duplicates);

/*

    результат: [ 3, 5 ]

*/

Скачать  Выполнить код

 
Приведенное выше решение может привести к дублированию значений на выходе. Чтобы справиться с этим, вы можете преобразовать результат в Set, в котором хранятся уникальные значения.

function findDuplicates(arr) {

    const filtered = arr.filter((item, index) => arr.indexOf(item) !== index);

    return [...new Set(filtered)]

}

const arr = [ 5, 3, 4, 2, 3, 7, 5, 6 ];

const duplicates = findDuplicates(arr);

console.log(duplicates);

/*

    результат: [ 3, 5 ]

*/

Скачать  Выполнить код

2. Использование Set.prototype.has() функция

Кроме того, для повышения производительности вы можете использовать ES6. Установить структуру данных для эффективной фильтрации массива.

Следующее решение находит и возвращает дубликаты, используя has() метод. Это работает, потому что каждое значение в наборе должно быть уникальным.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

function findDuplicates(arr) {

    const distinct = new Set(arr);        // для повышения производительности

    const filtered = arr.filter(item => {

        // удаляем элемент из набора при первой же встрече

        if (distinct.has(item)) {

            distinct.delete(item);

        }

        // возвращаем элемент при последующих встречах

        else {

            return item;

        }

    });

    return [...new Set(filtered)]

}

const arr = [ 5, 3, 4, 2, 3, 7, 5, 6 ];

const duplicates = findDuplicates(arr);

console.log(duplicates);

/*

    результат: [ 3, 5 ]

*/

Скачать  Выполнить код

Это все о поиске всех дубликатов в массиве в JavaScript.

Спасибо за чтение.

Пожалуйста, используйте наш онлайн-компилятор размещать код в комментариях, используя C, C++, Java, Python, JavaScript, C#, PHP и многие другие популярные языки программирования.

Как мы? Порекомендуйте нас своим друзьям и помогите нам расти. Удачного кодирования 🙂

Выбор способа вычисления близости строк очень сильно зависит от решаемой задачи.

Классическим подходом является вычисление расстояния Левенштейна.

Расстояние Левенштейна (редакционное расстояние, дистанция
редактирования) — метрика, измеряющая разность между двумя
последовательностями символов. Она определяется как минимальное
количество односимвольных операций (а именно вставки, удаления,
замены), необходимых для превращения одной последовательности символов
в другую. В общем случае, операциям, используемым в этом
преобразовании, можно назначить разные цены. Широко используется в
теории информации и компьютерной лингвистике.

const levenshtein = require('fast-levenshtein');

function compare(str, arr) {
    return arr.sort((a, b) => levenshtein.get(str, a) - levenshtein.get(str, b))[0];
}

const arr = ['toster','tester','tescer'];
const str = 'tescor';
console.log(compare(str, arr)); // tescer

Но существуют подходы к вычислению расстояния, которые лучше подходят для задач, связанных с естественными языками. Рекомендую ознакомиться с документацией к модулю natural.

const natural = require('natural');

function compareJaroWinkler(str, array) {
    return arr.sort((a, b) => natural.JaroWinklerDistance(str, b) - natural.JaroWinklerDistance(str, a))[0];
}

const arr = ['концерт в омске', 'концерт в комске', 'концерт в москве'];
const str = 'концерт в томске';

console.log('->', str);
console.log('<-', compareJaroWinkler(str, arr));


-> концерт в томске
концерт в омске 0.9874999999999999
концерт в комске 0.9483333333333334
концерт в москве 0.9616666666666668
<- концерт в омске

Добавить комментарий