Давайте сосредоточимся на той части вашей проблемы, которая заключается в сравнении элементов между несколькими массивами.Фактическая логика сравнения пока не важна.
Все начинается с вложенного цикла for:
var arr1 = [ "A", "B", "C" ];
var arr2 = [ "1", "2", "3" ];
// Runs arr1.length * arr2.length = 9 times
for (let i = 0; i < arr1.length; i += 1) {
for (let j = 0; j < arr2.length; j += 1) {
console.log(
"run", i * arr2.length + j,
"result", arr1[i], arr2[j]
);
}
}
Когда у вас есть функция, которая перебирает все пары двух массивов, остается только найти все возможные пары из одного списка массивов:
const arrays = [ [ "A" ], [ "B" ], [ "C" ] ];
for (let i = 0; i < arrays.length - 1; i += 1) {
// ^^^
for (let j = i + 1; j < arrays.length; j += 1) {
// ^^^^^
console.log(
JSON.stringify(arrays[i]),
JSON.stringify(arrays[j])
);
}
}
Теперь, когда у нас есть основы, мы можем связать их вместе и выполнить рефакторинг.Я должен признать, что рефакторинг - это что-то вроде личного вкуса, совершенно нормально оборачивать циклы for
в функции без других изменений.
Я назвал первый принцип combinations
и использовал reduce
и map
вместо for
петель.Второй цикл for
теперь содержится в allPairs
.
// Utilities:
const combinations = ([xs, ys]) =>
xs.reduce(
(cs, x) => cs.concat(ys.map(y => [x, y])),
[]
);
const allPairs = (xs) =>
xs.reduce(
(ps, x, i) => ps.concat(xs.slice(i + 1).map(y => [x, y])),
[]
);
const flatten = xxs => xxs.reduce((xs, ys) => xs.concat(ys))
const findMatches = (matchFn, arrays) => flatten(
allPairs(arrays).map(combinations)).filter(matchFn);
// App:
// Let's just stick to an easy example
const overlap = ([x, y]) => x === y;
console.log(
findMatches(
overlap,
[ [ 1, 2 ], [ 1, 3 ], [ 1, 2, 3], [ 4, 5 ], [ 1 ] ]
)
);
Этот подход возвращает вам пары перекрывающихся элементов.Вы должны будете включить свою собственную функцию overlaps
.Вы можете получить некоторую эффективность, используя find
вместо filter
, что возвращает первую перекрывающуюся пару.Если вы действительно хотите вернуться как можно раньше, прежде чем даже построить все комбинации пар, вам придется переместить еще кое-что (но я не могу представить, что производительность будет проблемой).