JavaScript:如果另一个对象在另一个属性中具有相同的值,则更改对象值

时间:2017-03-04 14:56:59

标签: javascript arrays sorting object javascript-objects

我有一个带有属性名称,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;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

您可以将朋友分配到同一个群组:如果任何人的首选人都在现有群组中,则会将他们添加到同一群组等。这样您就可以将所有人划分为不同的群组,确保一组中的人与另一组中的人之间没有偏好链。

然后,您可以按大小递减的顺序对这些组进行排序。首先选择最大的组,您可以将它们分配给第一个仍然有空间容纳整个组的表。

如果一个团体不能坐在任何桌子上,你应该放弃,因为这意味着(在你的4个桌子和6个座位的配置中)没有解决方案让每个人都与他们的首选人员坐在一起。

以下是执行该操作的功能。我添加了代码以使代码段与输入一起工作,但本质是在第一个函数中:

&#13;
&#13;
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;
&#13;
&#13;

使用代码段的整页模式查看整个表格。