我正在從 Apps 腳本中的名稱串列中匹配一對,但我正在嘗試找出一個附加條件。
<table>
<thead>
<tr>
<th>Names1</th>
<th>Names2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Glen</td>
<td>Adam</td>
</tr>
<tr>
<td>John</td>
<td>Matthew</td>
</tr>
<tr>
<td>Mitch</td>
<td>Damien</td>
</tr>
<tr>
<td>Daryl</td>
<td>Jason</td>
</tr>
<tr>
<td>Steve</td>
<td>Shane</td>
</tr>
<tr>
<td>Ricky</td>
<td>Stuart</td>
</tr>
</tbody>
</table>
這是解釋輸入和預期輸出的 Google 表格鏈接 - https://docs.google.com/spreadsheets/d/1nwu5j2ae_NQAmNQ5WlC-etd12lYMr4FDNKt3iAIjq4w/edit?usp=sharing
簽出單元格 A2 和 D1 中的行內注釋
在上面的示例中,Names1 列中的 Glen 映射到 Names2 列中的 Adam。我希望撰寫一個隨機匹配代碼,其中 Glen 與 Names1 和 Names2 列中的每個其他人進行映射,而沒有任何重復匹配。這是我迄今為止嘗試過的 -
方法 1: 使用簡單的 randomize() 函式,但重復匹配的頻率更高
方法 2: 使用自定義 shuffle 函式
function shuffleArray(range) {
var i,j,temp;
for (i=range.length-1; i>0; i--) {
j = Math.floor(Math.random()*(i 1));
temp = range[i];
array[i] = array[j];
array[j] = temp;
}
return range;
}
不幸的是,這種方法也顯示了重復匹配,但速率非常低,并且它沒有與兩個串列中的每個其他人進行詳盡的匹配。
任何幫助將非常感激。謝謝!
uj5u.com熱心網友回復:
您可以將您已經獲得的內容存盤在一個陣列中,并且每次獲得一對時,首先檢查該陣列是否尚未包含您找到的對。如果你想要每一個可能的對,沒有重復,你可以這樣做:
const found = [];
for(let i=0; i<range.length; i ){
for(let j=i 1; j<range.length; j ){
const str = `${range[i]}_${range[j]}`;
if(!found.includes(str)){
found.push(str);
}
}
}
uj5u.com熱心網友回復:
解決方案1
function solution1() {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName(`Solution1`)
const personsList = sheet.getRange(`A3:A`)
.getValues()
.filter(String)
.flat()
const teamsGenerated = sheet.getRange('C3:3')
.getValues()
.flat()
.filter(String)
.length
let newTeam
if (teamsGenerated) {
const previousTeams = sheet.getRange(3, 3, personsList.length, teamsGenerated)
.getValues()
newTeam = randomize(personsList)
while (previousTeams.some((i, index) => i.includes(newTeam[index]))) {
newTeam = randomize(personsList)
}
sheet.getRange(3, 3 teamsGenerated, newTeam.length)
.setValues(newTeam.map(i => [i]))
} else {
newTeam = randomize(personsList)
sheet.getRange(3, 3 teamsGenerated, newTeam.length)
.setValues(newTeam.map(i => [i]))
}
}
function randomize(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array
}
從第一列中取出所有名稱,我們查看是否已經生成了團隊。如果找到球隊,則生成一個新球隊,其中沒有球員與以前的球隊處于相同位置,直到找到為止;然后插入下一個可用列。如果沒有找到團隊,請插入一個隨機團隊。
uj5u.com熱心網友回復:
Glen 與 Names1 和 Names2 列中的所有其他人映射,沒有任何重復匹配
不清楚為什么要在 Apps 腳本中執行此操作,因為普通的電子表格公式就足夠了。您可以像這樣以隨機順序將每個名稱映射到每個其他名稱:
=transpose( { A3; sort( filter( A$3:A, len(A$3:A), A$3:A <> A3 ), randarray( counta( filter( A$3:A, len(A$3:A), A$3:A <> A3 ) ) ), true ) } )
請參閱示例電子表格中的新解決方案1 表。要獲得另一個迭代,請單擊單元格中的復選框D2。
預期的輸出只是一次迭代。下次當我運行代碼時,我希望看到每個人都有一組不同的配對而不會重復。
Team 1,Team 2
這聽起來像是一個不同的問題,但您可以將名稱劃分為在單元格中使用此公式A3:A給出的團隊數量:B3C3
=arrayformula(
query(
query(
iferror(
if(
{ 1, 1, 0 },
floor( mod( sequence(counta(A2:A)) - { 1, 1 }, { 9^9, B3 } ), { B3, 1 } ),
transpose( split( regexreplace( query( transpose( query(
transpose( sort( A3:A, if( len(A3:A), randbetween( sign(row(A3:A)), 9^9 ), iferror(1/0) ), true ) & char(9) ),
"", 9^9 ) ), "", 9^9 ), "\s $", "" ), char(9) & " ", false, true ) )
)
),
"select max(Col3) where Col3 <> '' group by Col1 pivot Col2", 0
),
"offset 1", 0
)
)
該公式將創建一個列出團隊的表格,每列一個團隊,名稱隨機分成多個團隊,名稱不重復。
請參閱示例電子表格中的新解決方案2 表。要隨機分組,請單擊單元格中的復選框B5。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/473311.html
