Я пытаюсь организовать массив, который у меня есть, в соответствии с определенными условиями, которые должны быть выполнены.
У меня есть 3 вида массивов: Массив людей
var array1 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
Массив дат
var array2 = ["date1","date2","date3","date4"]
Для каждого значения в массиве2 у меня есть соответствующие отдельные массивы (или 2D-массивы, честно говоря, не знаю, что лучше)
var date1Group1 = [1,6,7,8]
var date1Group2 = [4,5,9]
var date1Group3 = [6,17,15,3,11]
ИЛИ
var date1Groups = [[1,6,7,8],[4,5,9],[6,17,15,3,11]]
Каждая дата имеет свои соответствующие групповые массивы
var date2Groups = [...]
...
var date4Groups = [...]
Что мне нужно сделать, так это пропорционально распределить значения массива1 в новый массив, соответствующий его разделению на массив2.длина. В данном конкретном случае, поскольку:
array1.length = 18
array2.length = 4
У меня может быть, например, 1 2D-массив из 2 подмассивов по 5 значений и 2 подмассива по 4 значения ИЛИ 4 отдельных массива для каждой группы:
var arrayResultDate = [[v1,v2,v3,v4,v5],[v1,v2,v3,v4,v5],[v1,v2,v3,v4],[v1,v2,v3,v4]]
ИЛИ
var arrayResultDate1 = [v1,v2,v3,v4,v5]
var arrayResultDate2 = [v1,v2,v3,v4,v5]
var arrayResultDate3 = [v1,v2,v3,v4]
var arrayResultDate4 = [v1,v2,v3,v4]
Чтобы распределить их, мне нужно проверить, что значения, присвоенные каждому из этих новых массивов, не повторяются в одной и той же группе соответствующей даты. Например:
//This is valid be because no value is repeated in any of the groups for date1
arrayResultDate1 = [2,4,7,14,18]
//This is NOT VALID because values 6 and 8 are in date1Group1 / date1Groups[0]
arrayResultDate1 = [3,6,8,18,12]
То, что я хотел сделать, это сначала назначить от array1 [0] до array1 [3], от arrayResultDate1 до arrayResultDate4 (по 1 каждому)
arrayResultDate1.push(array1[0])
arrayResultDate2.push(array1[1])
arrayResultDate3.push(array1[2])
arrayResultDate4.push(array1[3])
ИЛИ
arrayResultDate[0].push(array1[0])
arrayResultDate[1].push(array1[1])
arrayResultDate[2].push(array1[2])
arrayResultDate[3].push(array1[3])
Затем используйте циклы, чтобы пройтись по остальным значениям в массиве1 и проверить, соблюдаются ли критерии в каждом результирующем массиве. Что касается массива, если условия выполнены, или перейти к следующему, если это не так.
Условия: Если вы пытаетесь назначить array1[x] для arrayResultDate1, проверьте, находятся ли значение array1[x] И значения уже в arrayResultDate1 одновременно в какой-либо из групп для date1:
date1Group1 = [1,6,7,8]
date1Group2 = [4,5,9]
date1Group3 = [6,17,15,3,11]
Если указанные значения НЕ ЯВЛЯЮТСЯ одновременно ни в одной из групп, то
arrayResultDate1.push(array1[x])
Если значения НАХОДЯТСЯ хотя бы в одной из групп, перейдите к следующему результирующему массиву и проверьте его соответствующие группы (в этом случае это будет arrayResultDate2, поэтому date2Group1, date2Group2 и т. д.)
Я не смог правильно организовать код из-за циклов внутри других циклов, которые, как я полагаю, необходимы. Я надеюсь, что это немного более ясно. Пожалуйста, дайте мне знать, если это все еще не так.
@doubleunary и TheMaster. Спасибо за ваши ответы. Я внес некоторые изменения в свой вопрос. Я надеюсь, что это немного более ясно.
Добро пожаловать в StackOverflow. пожалуйста, найдите время и прочитайте Как спросить с минимально воспроизводимым примером. Удачи
Может быть, это просто остаточное головокружение от слишком быстрого вставания, но при случайном чтении я не вижу в этом особого смысла. Это не ужасно, но вы говорите нам больше о том, как делать то, что вы хотите, чем о том, чего вы на самом деле хотите. Один совет: не говорите: «Я хочу А или, может быть, Б». Принимать решение. И компактно приведите пример вашего ввода с соответствующим выводом, который вы ищете. Объясните что-нибудь неясное об отношениях между вводом и выводом, но больше сосредоточьтесь на том, какие данные куда идут, а не на том, как кто-то может это реализовать.



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


Используйте Array.filter() и Array.sort(), например:
function test() {
const people = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,];
const criteria = [
{ label: 'date1', mutuallyExclusive: [[1, 6, 7, 8,], [4, 5, 9,], [6, 17, 15, 3, 11,],], },
{ label: 'date2', mutuallyExclusive: [[1, 6,],], },
{ label: 'date3', mutuallyExclusive: [[1, 7,],], },
{ label: 'date4', mutuallyExclusive: [[1, 8,],], },
];
const assignments = distributeObjectsToGroups(people, criteria);
console.info(assignments);
}
/**
* Distributes objects to groups observing multiple mutual exclusivity criteria.
*
* Processes each object in turn in the order they appear in the objects array.
* Attempts to make result groups approximately equal size by placing each object
* in the currently smallest group.
* Puts objects that do not fit in any group in an 'unassigned' group.
*
* @param {Object[]} objects The objects to place into groups, as in [1, 2, 3, 4,].
* @param {Object[]} groups An array of group labels and mutual exclusivity criteria.
* Each criteria is a 2D array that lists objects that should be
* mutually exclusive and not appear in the same result group.
* [
* { label: 'date1', mutuallyExclusive: [[1, 2, 3,], [2, 4,]], },
* { label: 'date2', mutuallyExclusive: [[2, 3,],], },
* ]
* @return {Object} The group labels and objects placed in each group.
* { date1: [1, 4,], date2: [2,], unassigned: [3,], }
*/
function distributeObjectsToGroups(objects, groups) {
// version 1.1, written by --Hyde, 3 November 2022
// - see https://stackoverflow.com/a/74294212/13045193
const result = { unassigned: [], };
groups.forEach(group => result[group.label] = []);
objects.forEach(object => {
const suitable = groups
.filter(group =>
!group.mutuallyExclusive.some(exclude =>
exclude.includes(object) &&
result[group.label].some(object2 => exclude.includes(object2)))
)
.sort((a, b) => result[a.label].length - result[b.label].length);
if (suitable.length) {
result[suitable[0].label].push(object);
return;
}
result.unassigned.push(object);
});
return result;
}
Тестовый запуск регистрирует это:
{
date1: [1, 5, 10, 13, 17],
date2: [2, 6, 9, 14, 18],
date3: [3, 7, 11, 15],
date4: [4, 8, 12, 16],
unassigned: [],
}
См. Сценарий приложения в Stack Overflow.
Спасибо @doublenary! Ух ты! Я бы определенно никогда не смог сделать это с моими знаниями, ха-ха, всего один вопрос: есть ли способ установить максимальное количество присваиваемых значений для каждой даты? Используя более точные критерии, где у меня есть 20 значений в людях, больше ограничений и те же 4 даты, я получаю: 18.0] date3=[3.0, 7.0, 11.0, 15.0, 19.0] date4=[4.0, 8.0, 12.0, 16.0] Можно ли установить, например, в этом случае максимальное количество 5 значений на дату?
Неважно! Я нашел код для перетасовки [людей] каждый раз перед запуском вашего скрипта, и у меня больше не было проблем. Я не возражаю, если мне нужно будет запустить его пару раз, если это когда-нибудь произойдет в будущем. Еще раз спасибо!
@doubleunary Группы рассчитаны на дату. Предоставленные группы предназначены только для "date1". Сказав это, Серджио. Было бы неплохо, если бы вы предоставили все группы на каждую дату. Предоставьте в качестве минимального воспроизводимого примера ввод и ожидаемый результат для ввода.