2017-03-04 1 views
0

Ich habe ein Array von Objekten mit den Eigenschaften name, pref und table. Ich muss prüfen, ob ein Objekt den gleichen Präferenzwert hat wie jeder andere Objektname. Ich habe etwas Code geschrieben, aber es scheint nicht zu funktionieren.JavaScript: Ändern des Objektwerts, wenn ein anderes Objekt denselben Wert in einer anderen Eigenschaft hat

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

Ich habe dir ein Schnipsel gemacht. Bitte kürzen Sie es, um das Problem mit so wenig Code wie möglich zu zeigen – mplungjan

+0

@mplungjan Oh, tut mir leid. – jscoder001

+0

@ jscoder001, wenn ich wüsste, was du ** wirklich willst ** (und die letzten drei Fragen machen es nicht klar), könnte ich dir helfen. Bitte fügen Sie den Zweck des Codes und was Sie gerne erreichen möchten. –

Antwort

2

Sie Freunde zur gleichen Gruppe zuweisen könnte: wenn jemand Person bevorzugt ist in einer bestehenden Gruppe ist, werden sie in derselben Gruppe hinzugefügt, usw. Auf diese Weise können Gruppe alle Personen, die in verschiedene Gruppen, in denen es sicher ist, dass es keine Präferenzkette von einer Person in einer Gruppe zu einer Person in einer anderen Gruppe gibt.

Dann könnten Sie diese Gruppen in der Reihenfolge der absteigenden Größe sortieren. Wenn Sie zuerst die größten Gruppen nehmen, können Sie sie der ersten Tabelle zuweisen, die noch Platz für die gesamte Gruppe bietet.

Wenn eine Gruppe nicht an einem Tisch sitzen kann, sollten Sie aufgeben, da dies bedeutet (in Ihrer Konfiguration von 4 Tabellen und 6 Plätzen) gibt es keine Lösung, um alle mit ihrer bevorzugten Person zu setzen.

Hier folgt eine Funktion, die das tut. Ich habe Code hinzugefügt, um die Schnipsel Arbeit mit Eingabe zu machen, aber das Wesentliche ist in der ersten Funktion:

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>

Verwenden Sie die Vollseitenmodus des Snippet die gesamte Tabelle zu sehen.

+1

Sie geben niemals auf! –

+0

@trincot Wow, ich denke du hast es vielleicht getan. Nur um zu klären, gibt es JS, die ich weglassen sollte oder Sie beziehen sich auf den HTML-Code als den Code, den Sie hinzugefügt haben.Vielen Dank für deine Hilfe. – jscoder001

+0

Der Code außerhalb der ersten Funktion dient dazu, die Schnittstelle zum HTML bereitzustellen, die Dateneingabe zu ermöglichen und bei zufälligen Eingaben Hilfe zu bieten. Aber die Logik ist in der ersten Funktion. Es sollte möglich sein, es in Ihren Code ohne viel Aufwand zu injizieren. Ich habe nur bemerkt, dass Sie "Daten" als global hatten. Es wäre besser, es als Argument an "Sitz" zu übergeben. Auf diese Weise muss diese Funktion nicht auf Globals verweisen. – trincot

Verwandte Themen