JSFiddle - React, Tailwind, and code Playground
HTML
<div id="container"></div>
CSS
#container img {
display: none;
}
#container .column {
width: 50%;
display: inline-block;
vertical-align: top;
}
#container .column .image-padding {
padding: 2px;
position: relative;
}
#container .column .image-padding:after {
content: attr(title);
padding: 1px 5px;
background: rgba(0, 0, 0, .8);
position: absolute;
top: 5px;
left: 5px;
color: white;
}
#container .column img {
width: 100%;
display: block;
}
JavaScript
function balance(numGroups, items, fetchValue){
function delta(a, b){
var da = a-avg, db = b-avg;
return da*da + db*db;
}
function testAndSwitchItems(a,b){
var valueA, valueB,
lengthA = a.length, lengthB = b.length,
indexA = lengthA, indexB = lengthB,
bestDelta = delta(a.sum, b.sum);
//test every item in this first column against every value in the second column
for(var i = 0; i <= lengthA; ++i){
//accessing a not available index of an Array may deoptimize this function
//that's why i check the index before accessing the element.
valueA = (i < lengthA && a[i] || nullElement).value;
for(var j = 0; j <= lengthB; ++j){
valueB = (j < lengthB && b[j] || nullElement).value;
//test wether it would be an improvement to switch these items
var d = delta(
a.sum + valueB - valueA,
b.sum + valueA - valueB
);
//find the best combination
if(d < bestDelta){
indexA = i;
indexB = j;
bestDelta = d;
}
}
}
var elmA = indexA < lengthA && a[indexA],
elmB = indexB < lengthB && b[indexB],
tmp;
if(elmA && elmB){
//switch items
a[indexA] = elmB;
b[indexB] = elmA;
}else if(elmA){
//move an item from a to b
b.push(elmA);
tmp = a.pop()
if(elmA !== tmp)
a[indexA] = tmp;
}else if(elmB){
//move an item from b to a
a.push(elmB);
tmp = b.pop()
if(elmB !== tmp)
b[indexB] = tmp;
}else{
//no switch would improve the result
return false;
}
//compute the new sums per group
valueA = (elmA || nullElement).value;
valueB = (elmB || nullElement).value;
a.sum += valueB - valueA;
b.sum += valueA - valueB;
return true;
}
function initGroupsAndReturnSum(sum, item, i){
var value = fetchValue? fetchValue(item): item;
//distribute the items
if(i<numGroups){
var group = groups[i] = [];
group.sum =...