如何在没有任何两个相邻值相同的情况下对数组进行随机排序



我有一个来自PHP的正则表达式,需要将其转换为JavaScript

基本上,我有一个数组[A,B,C,A,B,C

这个数组按随机顺序排列,然后我需要对数组进行排序,使以下两个值都不相同。

这是PHP中的函数:

function shuffleTracks($array) {
shuffle($array);
$string = implode(' ',$array);

foreach(array_unique($array) as $v) {
$pullcount = $pushcount1 = $pushcount2 = 0;
$string = preg_replace("/$v (?=$v)/","",$string,-1,$pullcount);  // remove the first value of each conflicting pair
$string = preg_replace("/ K(?<!$v )(?!$v)|^(?!$v)/","$v ",$string,$pullcount,$pushcount1);  // foreach removal, re-insert value(s) where valid
if($pullcount <= $pushcount1) {
$string = preg_replace("/$(?<!$v)/"," $v",$string,$pullcount-$pushcount1,$pushcount2);
}
if($pullcount != $pushcount1 + $pushcount2) {
$error = "Failure while replacing $v $pullcount & ".$pushcount1 + $pushcount2."n";
echo $error;
break;
}
}
$array = explode(" ",$string);
return $array;
}
$array = [
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C'];
$array = shuffleArray($array);

这就是我目前在JavaScript中所拥有的(我将preg_replace函数重新创建为JS(;

function preg_replace(object) {
var pattern, replacement, subject, limit, count, output;
(object.hasOwnProperty('pattern')) ? pattern = object.pattern : console.log('error');
(object.hasOwnProperty('replacement')) ? replacement = object.replacement : console.log('error');
(object.hasOwnProperty('subject')) ? subject = object.subject : console.log('error');
(object.hasOwnProperty('limit')) ? limit = object.limit : limit = -1;
(object.hasOwnProperty('count')) ? count = object.count : count = null;
if (limit == -1) {
var regex = new RegExp(pattern, "g");
subject = subject.replace(regex, () => {
count++;
return replacement
});
} else {
var regex = new RegExp(pattern);
for (var i = 0; i < limit; i++) {
subject = subject.replace(regex, () => {
count++;
return replacement;
})
}
}
(count != null) ? output = { subject, count } : output = { subject }
return output
}
function shuffleArray(array) {
const shuffle = (array) => {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
shuffle(array);
let string = array.join(' ');
let unique = [...new Set(array)];
unique.forEach((v) => {
var pullcount = 0,
pushcount1 = 0,
pushcount2 = 0;
object = preg_replace({ pattern: `${v} (?=${v})`, replacement: ``, subject: string, limit: -1, count: pullcount });                            // remove the first value of each conflicting pair
pullcount = object.count;
string = object.subject;
object = preg_replace({ pattern: `K(?<!${v} )(?!${v})|^(?!${v})`, replacement: `${v} `, subject: string, limit: pullcount, count: pushcount1 }); // foreach removal, re-insert value(s) where valid
pushcount1 = object.count;
string = object.subject;
if (pullcount <= pushcount1) {
object = preg_replace({ pattern: `$(?<!${v})`, replacement: ` ${v}`, subject: string, limit: pullcount - pushcount1, count: pushcount2 });
pushcount2 = object.count;
string = object.subject;
}
if (pullcount != (pushcount1 + pushcount2)) {
// console.log(`Failure while replacing ${v} ${pullcount} & ${pushcount1 + pushcount2} n`);
return;
}
})
array = string.split(' ');
return array;
}
var array = [
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C'];

console.log(array.join(" "));
console.log(array.length);
array = shuffleArray(array);
console.log(array.join(" "));
console.log(array.length);

然而,\K参数在JavaScript中不存在,因此我的数组没有被正确地打乱。。。

object = preg_replace({ pattern: `K(?<!${v} )(?!${v})|^(?!${v})`, replacement: `${v} `, subject: string, limit: pullcount, count: pushcount1 });

主要是,重复出现的情况会从字符串中剥离出来,但不会放回,从而产生一个长度不再相等的新数组。请帮忙。

任何有解的数组都可以随机排序,而不会有任何两个相邻的值相同

我在做什么的每个部分上面都写了等效的regexp。

// First a simple shuffle function
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
let temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
function shuffleSort(array) {
let unique = [...new Set(array)];
unique.forEach((v) => {
var pullcount = 0,
pushcount1 = 0,
pushcount2 = 0;
// regExp(/${v} (?=${v})/, "g")
for (var i = 0; i < array.length; i++) {
if ((array[i] == v) && (array[i+1] == v)) {         // "${v} (?=${v})"
array.splice(i, 1)
pullcount++;
i--;
}
}
// regExp(/ K(?<!${v} )(?!${v})|^(?!${v})/)
for (var i = 0; i < array.length; i++) {
if (array[0] != v) {                                // "|^(?!${v})"
array.splice(0, 0, v);
pushcount1++;
}
if ((array[i] != v) && (array[i-1] != v)) {         // " K(?<!${v} )(?!${v})"
array.splice(i, 0, v);
pushcount1++;
}
if (pushcount1 >= pullcount) {
break;
}
}
// regExp(/$(?<!${v})/)
if (pullcount <= pushcount1) {
for (var i = 0; i < pullcount - pushcount1; i++) {
if (array[array.length - 1] != v) {             // "$(?<!${v})"
array.push(v);
pushcount2++;
}
}
}
if (pullcount != (pushcount1 + pushcount2)) {
console.log(`Failure while replacing ${v} ${pullcount} & ${pushcount1 + pushcount2} n`);
}
})
return array;

}
var arr = [
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C',
'A', 'B', 'C'];
shuffle(arr);  // Let's randomize it first or our next function has nothing to do! :)
shuffleSort(arr); // Magic!
/* Check results visually */
console.log(arr.join(" "));

/* Another check */
arr.forEach((el, index) => {
if (arr[index] == arr[index + 1]) {
console.log(index);
console.log(el);
window.alert('duplicates!');  // <-- This will never happen :)
}
})

最新更新