Есть массив из чисел (идентификаторов), в котором значения элементов упорядочены по возрастанию:
let arr = [1,2,3,4];
Мы хотим создать все возможные пары чисел и сложить их в новый массив:
let new_arr = [];
Делаем генерацию через цикл:
for(let x of arr){ for(let y of arr){ new_arr.push([x,y]) } }
В первом цикле мы идём по элементам массива. Во втором цикле мы отрабатываем остановку на одном элементе, делая ещё один проход.
Результат перестановок:
Наш массив состоял из четырёх элементов, поэтому генерация всех возможных пар составила шестнадцать вариантов. То есть «пара» — это степень, в которую нужно возвести количество элементов.
Как сгенерировать все возможные пары из массива чисел в JavaScript, чтобы они не повторялись?
Эта задача немного отличается от предыдущей. В этом случае нам нужно игнорировать варианты пар вида [1,1] или [2,2]. Как это запрограммировать?
Пусть у нас будут те же самые исходные данные:
let arr = [1,2,3,4]; let new_arr = [];
А вот в цикл нам нужно будет добавить условие:
for(let x of arr){ for(let y of arr){ if(x != y){new_arr.push([x,y])} else{continue} } }
Смотрим на текущую ситуацию:
Мы используем ветвление при помощи оператора «if«. Все ситуации, где элементы равны друг другу мы игнорируем и пропускаем оператором «continue«.
Обратите внимание! Количество возможных вариантов сократилось ровно на количество элементов массива. Мы получили 12 пар вместо 16 возможных.
Как сгенерировать все возможные пары из массива чисел в JavaScript, чтобы они не повторялись и чтобы элементы пары встречались только один раз?
В этой задаче мы шагаем ещё на одну ступень глубже. Мы хотим оставить только пару вида [1,2] и убрать пару [2,1]. Как это сделать?
Нам нужно подкорректировать условие. В этот раз мы будем игнорировать пары, в которых второй элемент больше первого.
Пусть у нас будут те же самые исходные данные. Оригинальный массив также упорядочен по возрастанию:
let arr = [1,2,3,4]; let new_arr = [];
В цикл нам нужно будет добавить условие (x < y):
for(let x of arr){ for(let y of arr){ if(x != y && x < y){new_arr.push([x,y])} else{continue} } }
Результат генерации:
В этом случае мы сократили предыдущий результат ровно на половину. В прошлой версии было 12, а теперь 6.
Формула общего количества таких перестановок проста. Считаем количество всех перестановок, вычитаем из него количество элементов массива и делим итог на два.
Универсальное решение получения возможных пар значений для любого массива в JavaScript
До этого момента мы использовали цикл, который ходит по значениям свойств. Но это будет работать только в упорядоченных массивах чисел. Нам же нужно иметь универсальное решение, которое могло бы делать перестановки любых типов данных — строк, объектов и т.п..
Все перестановки:
function all_permutations(arr){ let a = []; for(let x in arr){ for(let y in arr){ a.push([arr[x], arr[y]]) } }; return a; };
Тестируем работу всех перестановок:
all_permutations([1,2,3,4,5]); all_permutations(['у','а','м','о','б']);
Скриншот из консоли браузера:
Все перестановки без одинаковых пар:
function all_permutations_without_identical_pairs(arr){ let a = []; for(let x in arr){ for(let y in arr){ if(x != y){a.push([arr[x], arr[y]])} else{continue} } }; return a; };
Тесты:
all_permutations_without_identical_pairs([1,2,3,4,5]); all_permutations_without_identical_pairs(['у','а','м','о','б']);
Перестановки без одинаковых пар и похожих наборов элементов:
function permutations_without_similar_sets_of_elements(arr){ let a = []; for(let x in arr){ for(let y in arr){ if(x != y && x < y){a.push([arr[x], arr[y]])} else{continue} } }; return a; };
Тесты:
permutations_without_similar_sets_of_elements([1,2,3,4,5]); permutations_without_similar_sets_of_elements(['у','а','м','о','б']);