2

I have an array of objects which looks like this:

[
    {
      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"
    }
  ]

I need to iterate trough every object and generate smaller array chunks that should:

  1. Be of a length of 3
  2. Contain current object entry of pVerb
  3. Be placed on random positions

something like following:

[
  [
    "!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!"
  ]
]

Currently I have something like this but it does not check for duplicate entries or randomize the positions:

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

I need array of chunks where a chunk would be [pVerb of first object, any other two pVerbs from any other two objects(unique)] next chunk would have [pVerb of second object, ...] etc.

6
  • To generate a unique random sequence on your array, check this Commented Oct 5, 2018 at 11:11
  • I'm not sure what you meant by randomize the positions - you want to shuffle the array when it is filled? Commented Oct 5, 2018 at 11:13
  • Yes, basically to shuffle chunks Commented Oct 5, 2018 at 11:14
  • To me, it doesn't make much sense, since the array will be generated randomly. But, if you would like to shuffle, you can just loop one through the array, generate a random index and switch elements... Commented Oct 5, 2018 at 11:18
  • Should the first entry remain in order like it does in your example, with only the last two being shuffled? Commented Oct 5, 2018 at 11:18

1 Answer 1

1

You can get a randomly ordered random selection of three elements from the array with the help of a shuffle:

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));

Now that you have three random values in an array, you want to make sure one of them is the current value – the one that corresponds to the pVerb. Check if it’s in there.

  • If it’s already present, nothing more needs to be done.
  • If it isn’t present, pick a random item to replace with it.
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;
};

This messes up the order of the array, so you’ll want to make a copy exclusively for shuffling use, since you’re iterating over the original array. All told, with types:

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));
Sign up to request clarification or add additional context in comments.

1 Comment

God bless you! Worked as expected

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.