Как распределить массив в соответствии с конкретными условиями в скрипте Google Apps?

Я пытаюсь организовать массив, который у меня есть, в соответствии с определенными условиями, которые должны быть выполнены.

У меня есть 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 Группы рассчитаны на дату. Предоставленные группы предназначены только для "date1". Сказав это, Серджио. Было бы неплохо, если бы вы предоставили все группы на каждую дату. Предоставьте в качестве минимального воспроизводимого примера ввод и ожидаемый результат для ввода.

TheMaster 02.11.2022 00:26

@doubleunary и TheMaster. Спасибо за ваши ответы. Я внес некоторые изменения в свой вопрос. Я надеюсь, что это немного более ясно.

Sergio Delgado 02.11.2022 01:57

Добро пожаловать в StackOverflow. пожалуйста, найдите время и прочитайте Как спросить с минимально воспроизводимым примером. Удачи

nima 02.11.2022 08:55

Может быть, это просто остаточное головокружение от слишком быстрого вставания, но при случайном чтении я не вижу в этом особого смысла. Это не ужасно, но вы говорите нам больше о том, как делать то, что вы хотите, чем о том, чего вы на самом деле хотите. Один совет: не говорите: «Я хочу А или, может быть, Б». Принимать решение. И компактно приведите пример вашего ввода с соответствующим выводом, который вы ищете. Объясните что-нибудь неясное об отношениях между вводом и выводом, но больше сосредоточьтесь на том, какие данные куда идут, а не на том, как кто-то может это реализовать.

Scott Sauyet 02.11.2022 15:37
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте 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 значений на дату?

Sergio Delgado 03.11.2022 02:25

Неважно! Я нашел код для перетасовки [людей] каждый раз перед запуском вашего скрипта, и у меня больше не было проблем. Я не возражаю, если мне нужно будет запустить его пару раз, если это когда-нибудь произойдет в будущем. Еще раз спасибо!

Sergio Delgado 03.11.2022 04:58

Другие вопросы по теме