如何根据匹配的参数从数组中选择一些随机id值?

问题描述 投票:2回答:7

我有一个700个问题对象的数组,如下所示:

[
  {
    _id: "5ca3216579a592b0910f70d4"
    question: "Who wrote Twilight series of novels?"
    answer: "Stephenie Meyer"
    category: "Art and Literature"
  },
  ...
]

我还有一个由3个选定的问题类别组成的数组,如下所示:

["Art and Literature", "Music", "History"] 

我基本上需要的是每个问题类别的4个随机问题。所以:

  • 4个随机的艺术与文学问题
  • 音乐的4个随机问题
  • 4个随机的历史问题

理想情况下,我认为将12个随机问题ID设置在基于这3个类别的新数组中会很好,所以我可以将它们发送到我的数据库。

怎么做?

javascript arrays random
7个回答
1
投票
const questions = [
    {
      _id: "5ca3216579a592b0910f70d4",
      question: "Who wrote Twilight series of novels?",
      answer: "Stephenie Meyer",
      category: "Art and Literature",
    }
  ]

const categories = ["Art and Literature", "Music", "History"];

const numberOfEachCategory = 2;


const randSelected = categories.map((category) => {
    const filtered = questions.filter((obj) => obj.category === category).slice();

    if(filtered.length > numberOfEachCategory) {
        const randomArray = [];

        for(let i = numberOfEachCategory; i > 0; i--) {
            randomArray.push(...filtered.splice(Math.floor(Math.random() * filtered.length), 1));
        }

        return randomArray;

    } else {
        return filtered;
    }
})

console.log(randSelected);

结果是数组数组。每个类别的每个内部数组


2
投票

您应该首先为每个类别创建一个问题数组,以便随机选择。

const art = arr.filter(question => question.category === 'Art and Literature');
const music = arr.filter(question => question.category === 'Music');
const history = arr.filter(question => question.category === 'History');

现在,只需为每个类别数组随机选择四次项目。

const categoryArrays = [art, music, history];

const results = [] // to store the selected ids 

for (i = 0, i < 3, i++) { // To iterate over the three categories 
  for (j = 0, j < 4, j++) { // To select four times 
    results.push(categoryArrays[i][Math.floor(Math.random() * categoryArrays[i].length)]._id);
  }
}

2
投票

这有几个步骤。首先,您需要过滤掉特定类别的项目列表。

const categories = ["Art and Literature", "Music", "History"];

for (let c of categories) {
    const itemsOfCategory = items.filter(i => item.category === c);
}

然后,您将要从筛选列表中选择4个随机项并返回它们。把它放在它自己的功能中似乎是最好的。

const getRandomItems = (items, categories, numberOfItems) => {
    const results = [];
    for (let c of categories) {
        const itemsOfCategory = items.filter(i => i.category === c);
        const pickedItems = [];
    for (let i = 0; i < numberOfItems; i += 1) {
      pickedItems.push(Math.trunc(Math.random()*itemsOfCategory.length))
        }
    results.push(pickedItems)
    }
  return results;
}

然后,您可以传入项目列表,所需类别以及所需项目数。

const randomItems = getRandomItems(items, categories, 4);


2
投票

您可以在map数组上使用categories,然后在回调中使用filter来获取类别匹配的对象数组。在第一次迭代时,它将给出一个数组,其中类别为Art and Literature,依此类推。然后运行另一个循环来生成4个随机数,并使用此随机数从过滤后的数组中获取一个随机问题。将该值存储在临时变量中并返回该值

let ques = [{
  _id: "5ca3216579a592b0910f70d4"
  question: "Who wrote Twilight series of novels?"
  answer: "Stephenie Meyer"
  category: "Art and Literature"
}]


let type = ["Art and Literature", "Music", "History"];

let randomQues = type.map(function(item) {
  let quesArrays = []
  let k = ques.filter(elem) {
    return elem.category === item;
  }) for (let i = 0; i < 4; i++) {
  let rand = Math.floor(Math.random() * k.length);
  quesArrays.push(rand)
}
return quesArrays;
})

2
投票

您可以使用reduce()按类别对所有问题ID进行分组,然后从这些数组中选择N个随机项:

const categories = ['cat1', 'cat2', 'cat3'];
const questions = Array.from({ length: 10 }, (_, i) => (
  { _id: i, question: `question ${i}`, answer: `answer ${i}`, category: categories[Math.floor(Math.random() * categories.length)]})
);
  
function randomQuestions(questions, categories, n) {
  // group the ids into arrays for each category asked
  const idsByCategories = questions.reduce((acc, x) => {
    if (categories.includes(x.category)) {
      acc[x.category] = [...(acc[x.category] || []), x._id];
    }
    return acc;
  }, {});
  // pick a number of random ids for each category
  return categories.map(cat => (idsByCategories[cat] || []).sort(() => 0.5 - Math.random()).slice(0, n));
}

console.log(JSON.stringify(randomQuestions(questions, ['cat1', 'cat3'], 2)));

console.log(questions);

随机数组选择代码采取from this answer


0
投票

使用shuffle函数来重新包含包含问题的数组,而不是仅通过匹配类别获得前4个结果。

这是伪代码:

let arrayOfQuestions =[];
let shuffledQuestions = _.shuffle(arrayOfQuestions); // _ is Lodash
let artAndLiteratureQuestions = _.find(shuffledQuestions, { category: 'Art and Literature' }

以同样的方式,您可以提取其他类别的问题。


0
投票

您可以使用此逻辑将所有结果集中在所有类别的一个班轮中:)只需要使用您的支票更改过滤器检查。

let list = [1,1,1,1, 1, 1,1, 3, 2, 3, 4, 5, 6 ];
let options = [1, 3];

const result = options.map((val) => {
  return list.filter(f => val === f ).map((v, i, ref) => {
    if(i<=3)
      return ref[parseInt(Math.random()*ref.length-i)]
}).slice(0, 3)
})

console.log(result);
© www.soinside.com 2019 - 2024. All rights reserved.