У меня есть массив объектов, который выглядит так:

[
    {
      pVerb: "ask somebody out",
      meaning: "invite on a date"
    },
    {
      pVerb: "ask around",
      meaning: "ask many people the same question"
    },
    {
      pVerb: "add up to something",
      meaning: "equal"
    },
    {
      pVerb: "back something up",
      meaning: "reverse"
    },
    {
      pVerb: "back somebody up",
      meaning: "support"
    },
    {
      pVerb: "blow up",
      meaning: "explode"
    }
  ]

Мне нужно перебрать каждый объект и сгенерировать меньшие фрагменты массива, которые должны:

  1. Быть длиной 3 человека
  2. Содержит текущую запись объекта pVerb
  3. Быть размещенным на случайных позициях

Что-то вроде следующего:

[
  [
    "!ask somebody out!",
    "add up to something",
    "back something up"
  ],
  [
    "add up to something",
    "!ask around!",
    "blow up"
  ],
  [
    "blow up",
    "back somebody up",
    "!add up to something!"
  ]
]

В настоящее время у меня есть что-то вроде этого, но он не проверяет повторяющиеся записи и не рандомизирует позиции:

const randomNumber = (max: number, min: number) => {
      const num = Math.floor(Math.random() * (max - min + 1)) + min;
      return num;
    };

    const array: any[] = [];
    for (const n of array) {
      array.push([
        n.meaning,
        array[randomNumber(0, array.length)]
          .meaning,
        array[randomNumber(0, array.length)]
          .meaning
      ]);
    }

TL : DR

Мне нужен массив фрагментов, где фрагмент будет [pVerb of first object, any other two pVerbs from any other two objects(unique)], следующий фрагмент будет иметь [pVerb of second object, ...] и т. Д.

2
Dimitry Ivashchuk 5 Окт 2018 в 14:06

1 ответ

Лучший ответ

Вы можете получить случайно упорядоченный случайный выбор из трех элементов из массива с помощью перемешивания:

const partialShuffle = (values, count) => {
  for (let i = 0; i < count; i++) {
    const j = Math.floor(Math.random() * (values.length - i)) + i;
    [values[i], values[j]] = [values[j], values[i]];
  }
};

const nums = [1, 2, 3, 4, 5, 6];
partialShuffle(nums, 3);
console.log('' + nums.slice(0, 3));
partialShuffle(nums, 3);
console.log('' + nums.slice(0, 3));
partialShuffle(nums, 3);
console.log('' + nums.slice(0, 3));

Теперь, когда у вас есть три случайных значения в массиве, вы хотите убедиться, что одно из них является текущим значением - тем, которое соответствует pVerb. Проверьте, есть ли оно там.

  • Если он уже присутствует, ничего делать не нужно.
  • Если его нет, выберите случайный предмет и замените им.
const randomTripleIncluding = (values, value) => {
  partialShuffle(values, 3);
  const triple = values.slice(0, 3);

  if (!triple.includes(value)) {
    triple[Math.floor(Math.random() * 3)] = value;
  }

  return triple;
};

Это приводит к нарушению порядка в массиве, поэтому вам нужно сделать копию исключительно для использования в случайном порядке, поскольку вы выполняете итерацию по исходному массиву. Все сказано, с типами:

const partialShuffle = (values: any[], count: number) => {
  for (let i = 0; i < count; i++) {
    const j = Math.floor(Math.random() * (values.length - i)) + i;
    [values[i], values[j]] = [values[j], values[i]];
  }
};

const randomTripleIncluding = <T>(values: T[], value: T): T[] => {
  partialShuffle(values, 3);
  const triple = values.slice(0, 3);

  if (!triple.includes(value)) {
    triple[Math.floor(Math.random() * 3)] = value;
  }

  return triple;
};

const input = [
  {pVerb: "ask somebody out", meaning: "invite on a date"},
  …
];

const scratchInput = input.slice();

const result = input.map(n => randomTripleIncluding(scratchInput, n));
1
Ry- 5 Окт 2018 в 12:04