我有一个带有属性名称,pref和table的对象数组。我需要检查一个对象是否具有与任何其他对象名称值相同的pref值。我已经编写了一些代码,但它似乎并没有起作用。
function seat() {
for (var i = 0; i < data.length; i++) {
if (data[i].pref != "") {
for (var c = 0; c < data.length; c++) {
if (data[i].pref == data[c].name) {
data[i].table = data[c].table
console.log(data[i].table + "first pref val");
console.log(data[c].table + "second pref val");
}
}
}
function randomize() {
let counts = [
[1, 6],
[2, 6],
[3, 6],
[4, 6]
];
data.forEach(obj => {
let i = Math.floor(Math.random() * counts.length);
obj.table = 'table' + counts[i][0];
if (--counts[i][1] == 0) counts.splice(i, 1);
})
}
randomize(1, 4);
console.log(data);
console.log("Right here ^");
};
};
var data = [{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
{
name: "",
pref: "",
table: ""
},
];
seat();
&#13;
答案 0 :(得分:2)
您可以将朋友分配到同一个群组:如果任何人的首选人都在现有群组中,则会将他们添加到同一群组等。这样您就可以将所有人划分为不同的群组,确保一组中的人与另一组中的人之间没有偏好链。
然后,您可以按大小递减的顺序对这些组进行排序。首先选择最大的组,您可以将它们分配给第一个仍然有空间容纳整个组的表。
如果一个团体不能坐在任何桌子上,你应该放弃,因为这意味着(在你的4个桌子和6个座位的配置中)没有解决方案让每个人都与他们的首选人员坐在一起。
以下是执行该操作的功能。我添加了代码以使代码段与输入一起工作,但本质是在第一个函数中:
function seat(data) {
// Key the persons by name and add some extra properties
const hash = data.reduce( (acc, person, i) =>
acc.set(person.name, Object.assign(person, {
id: i,
group: null
})), new Map );
const groups = [];
const free = new Set(hash.values());
while (free.size) {
const group = new Set();
let person = free.values().next().value; // first in Set
// Add chain of preferrences to same group
while (person && person.group === null) {
free.delete(person);
group.add(person);
person.group = group;
person = hash.get(person.pref);
}
if (person && person.group !== group) { // merge groups
group.forEach( p => {
p.group = person.group;
p.group.add(p);
});
} else {
groups.push(group); // add group
}
}
const counts = [6, 6, 6, 6];
groups.sort( (a, b) => b.size - a.size ) // descending size
.forEach( group => {
let table = counts.findIndex( count => count >= group.size );
if (table === -1) {
alert('No solution possible');
return;
}
counts[table] -= group.size;
// Assign table (table1, table2, table3 or table4)
group.forEach( person => person.table = 'table' + (table + 1) );
});
}
// Below follow the functions to make this demo work
(function populate() {
const persons = [...Array(6*4).keys()];
// template row:
const $row = $('<tr>').append(
$('<td>').append($('<input>')),
$('<td>').append(
$('<select>').addClass('pref')
.append($('<option>'), persons.map(function (i) {
return $('<option>').val(i+1).text('person' + (i+1));
}))
),
$('<td>').append(
$('<select>').addClass('table')
.append($('<option>'), [1,2,3,4].map(function (i) {
return $('<option>').val('table' + i).text('table' + i);
}))
)
);
// Fill table with names
$('table').append(
persons.map( i => {
$tr = $row.clone();
$('input', $tr).val('person'+ (i+1));
// Remove option to select the same person as preferred
$('.pref>option', $tr).get(i+1).remove();
return $tr;
})
);
})(); // execute immediately
function shuffle(a) {
for (let i = a.length; i; i--) {
let j = Math.floor(Math.random() * i);
[a[i - 1], a[j]] = [a[j], a[i - 1]];
}
}
// Allow to assign "random" choices for the preferred persons
$('#rand_pref').on('click', function () {
const persons = [...Array(6*4).keys()];
shuffle(persons);
$('tr').each(function (i) {
// Select kind-of-random preferred compagnion,
// but in a way that it is solvable
const j = persons.indexOf(i);
let k = ((j % 6)>>1 !== 1) ? j ^ 1
: j + Math.sign(Math.random() - 0.5);
$('.pref', this).val(persons[k] + 1);
});
});
// Allow names to be changed:
$('input').on('input', function() {
$('.pref>option[value=' + ($(this).closest('tr').index()+1) + ']')
.text($(this).val());
});
// On click: collect input, and generate solution
$('#assign').on('click', function() {
// collect input
var data = $('tr').map(function () {
return {
name: $('input', this).val(),
pref: $('.pref>option:selected', this).text(),
table: $('.table>option', this).val()
};
}).get();
// Calculate seating
seat(data);
// Display result
$('tr').each(function (i) {
$('.table', this).val(data[i].table);
});
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table></table>
<button id="rand_pref">Randomise preferred persons</button>
<button id="assign">Assign to tables</button>
&#13;
使用代码段的整页模式查看整个表格。