2017-03-04 65 views
0

我有一个包含属性名称,前缀和表格的对象数组。我需要检查一个对象是否具有与任何其他对象名称值相同的pref值。我写了一些代码,但它似乎并没有工作。JavaScript:如果另一个对象在另一个属性中具有相同值,则更改对象值

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();

+0

我让你成为一个片段。请缩短它以尽可能少的代码显示问题 – mplungjan

+0

@mplungjan哦,好的,对不起。 – jscoder001

+0

@ jscoder001,如果我想知道你真的想要**(最后三个问题没有说清楚),我可以帮你。请添加代码的目的以及您想要实现的目标。 –

回答

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); 
 
    }); 
 
});
<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>

使用片断的整版模式看到整个表。

+1

你永不放弃! –

+0

@trincot哇,我想你可能已经做到了。只是为了澄清是否有JS我应该忽略掉,或者你是指HTML作为你添加的代码。非常感谢你的帮助。 – jscoder001

+0

第一个函数之外的代码是为HTML提供接口,允许数据输入,并为随机输入提供一些帮助。但逻辑在第一个功能。应该可以在没有太多麻烦的情况下将其注入代码中。我只是注意到,你有'数据'作为一个全球性的。将它作为参数传递给“席位”会更好。这种方式,该功能不需要引用任何全局变量。 – trincot

相关问题