多数组的 math.random()-0.5

Posted

技术标签:

【中文标题】多数组的 math.random()-0.5【英文标题】:math.random()-0.5 for Multiple Array 【发布时间】:2018-08-22 18:12:33 【问题描述】:

我必须使用 jquery 对 3 个数组进行排序,但结果的顺序应该相同

第一个数组是文本答案,第二个是图像答案,第三个是音频答案,排序后所有数组应该是相同的顺序,但是当问题改变时它必须排序

var Textanswers = plugin.config.randomSort || plugin.config.randomSortAnswers ?
question.a.sort(function ()  return (Math.round(Math.random()) - 0.5); ) :
question.a;

var Imageanswer= plugin.config.randomSort || plugin.config.randomSortAnswers ?
 question.imga.sort(function ()  return (Math.round(Math.random()) - 0.5); ) :
 question.imga;


var Audioanswer= plugin.config.randomSort || plugin.config.randomSortAnswers ?
question.auda.sort(function ()  return (Math.round(Math.random()) - 0.5); ) :
question.auda;

【问题讨论】:

您想要对三个数组进行相似的随机排序?或者您想对所有数组进行随机排序,彼此独立? 这当然是可能的。但是您是否考虑过拥有具有文本/图像/音频属性的答案对象?您可以根据需要对这些对象进行排序,所有相关属性都将保持在一起。 我在这个中看不到 C#... 是的,我想对这三个数组进行类似的排序 因此,您想对数组进行洗牌,但使用以下规则(示例):如果 auda 的问题 5 最终出现在 auda[0] 中,则 imga 的问题 5 也应该在 imga[0 ]? 【参考方案1】:

有many ways 来洗牌,但我会在这个答案中使用你的:

const shuffle = xs => xs.sort(() => Math.round(Math.random()) - 0.5));

您的问题包含 3 个长度相似的数组。数组中的项目通过索引彼此“相关”:

question.a[i] ~ question.imga[i] ~ question.auda[i]

确保在洗牌时尊重这些关系的一种方法是洗牌“三重奏”项目而不是单个数组。

shuffle([
  [question.a[0], question.imga[0], question.auda[0]],
  /* ... */
])

这带来了两个挑战: 1.从多个数组中创建一个相关项数组 2.排序后,从打乱的三元组中提取单个数组

1。压缩

让我们定义一个 zip 函数:

const zip = (xs, ...others) =>
  xs.map(
    (x, i) => [x].concat(others.map(ys => ys[i]))
  );
  
console.log(zip([1, 2, 3], ["a", "b", "c"], ["I", "II", "III"]));

2。提取

现在,回到三个单独的数组,我们创建一个“问题构造函数”,它接受一个 [a, imga, auda] 数组并将其转换为具有命名属性的对象:

const Question = ([a, imga, auda]) => ( a, imga, auda )

或者,更通用的:

const zipped = [[1, "a", "I"], [2, "b", "II"], [3, "c", "III"]];

const unzip = xss => xss.reduce(
  (t1, t2) => t1.map((x, i) => [].concat(x).concat(t2[i]))
);

console.log(unzip(zipped));

把它们放在一起:

const q = 
  question: "Are my answers shuffled?",
  answers: [ "Yes", "No", "Maybe" ],
  audio: [ "yeeeeaaah", "naaaa", "ehhhh" ],
  img: [ "✔", "⛔️", "❓" ]
;

// Utils
const zip = (xs, ...others) =>
  xs.map(
    (x, i) => [x].concat(others.map(ys => ys[i]))
  );

const unzip = xss => xss.reduce(
  (t1, t2) => t1.map((x, i) => [].concat(x).concat(t2[i]))
);

const shuffle = xs => xs.sort(() => Math.random() - 0.5)

// Question shuffler implementation
const shuffleQuestion = q => 
  const [answers, audio, img] =
    unzip(shuffle(zip(q.answers, q.audio, q.img)));
    
  return Object.assign(
    , q,  answers, audio, img 
  );
;

// Three versions of the question that *might* have 
// differently ordered answers
console.log(shuffleQuestion(q));
console.log(shuffleQuestion(q));
console.log(shuffleQuestion(q));
  

当然,你也可以为Matthew提出的方法创建一个javascript实现:

const reorder = order => xs => order.map(i => xs[i]);
const range = length => Array.from( length , (_, i) => i);
const shuffle = xs => xs.sort(() => Math.random() - 0.5);

const myShuffle = reorder(shuffle(range(3)));

console.log(myShuffle([1, 2, 3]));
console.log(myShuffle(["a", "b", "c"]));
console.log(myShuffle(["I", "II", "III"]));

【讨论】:

【参考方案2】:

一种方法是使用索引数组,然后将其随机排列。

然后您可以使用打乱数组中的索引以相同的随机顺序访问其他每个数组的元素。

以下 C# 代码演示了该方法(以及标准的随机播放算法):

using System;
using System.Collections.Generic;
using System.Linq;

namespace Demo

    class Program
    
        static void Main()
        
            int[]    array1 = 1, 2, 3, 4, 5;
            string[] array2 = "One", "Two", "Three", "Four", "Five";
            double[] array3 = 0.1, 0.2, 0.3, 0.4, 0.5;

            // Create an array of indices the same length as the arrays to be shuffled.

            var indices = Enumerable.Range(0, array1.Length).ToArray();

            // Shuffle the indices.

            Shuffle(indices, new Random());

            // Now you can use the shuffled indices to access all the arrays in the same random order:

            foreach (int index in indices)
            
                Console.WriteLine($"array1[index], array2[index], array3[index]");
            
        

        // Standard shuffle.
        public static void Shuffle<T>(IList<T> array, Random rng)
        
            for (int n = array.Count; n > 1;)
            
                int k = rng.Next(n);
                --n;
                T temp = array[n];
                array[n] = array[k];
                array[k] = temp;
            
        
    

【讨论】:

感谢重播 .. 并更正,但我想要相同的 Jquery 或 JavaScript 代码 @DonaannaKurian 如果你不想要 C# 为什么要在你的问题上加上 C# 标签?

以上是关于多数组的 math.random()-0.5的主要内容,如果未能解决你的问题,请参考以下文章

关于 JavaScript Math.random() 和基本逻辑的问题

javascript 中根据sort 方法随机数组 (Math.random)

为啥 JavaScript Math.random() 多次返回相同的数字

给数组随机打乱

JS:数组的 Math.random

JS:数组的 Math.random