2017-03-04 9 views
0

プロパティ名がname、pref、およびtableのオブジェクトの配列があります。あるオブジェクトが他のオブジェクト名の値と同じ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、**あなたが本当にほしい**ことを知っていれば**(最後の3つの質問ではわかりません)、私はあなたを助けることができます。コードの目的と達成したいことを追加してください。 –

答えて

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

関連する問題