Skip to content

Instantly share code, notes, and snippets.

@SergProduction
Created November 1, 2017 20:44
Show Gist options
  • Select an option

  • Save SergProduction/173bc0303a0b160fbda47f8b4fa6c60c to your computer and use it in GitHub Desktop.

Select an option

Save SergProduction/173bc0303a0b160fbda47f8b4fa6c60c to your computer and use it in GitHub Desktop.
/**
* @param {object[]} data [{ name:'group', [elementName]:[] }, ...]
* @param {number} columns 3
* @param {number} groupHeight высота между групапами, 1 эквивалентно высоте одного элемента группы
* @param {string} elementName имя свойства элементов в группе
* @returns {object[]} [{ column:1, data: [group, ...] }, ...]
*/
function sortGroupColumn(data, columns, groupHeight, elementName) {
// в каком столбце какие данные (data); len - общее кол-во значений в группах
const column = {}
for (let i = 1; i <= columns; i++) {
column[i] = { len: 0, data: [] }
}
data.forEach((group) => {
const smalColumnNum = Object.keys(column).reduce((prev, next) => {
if (column[prev].len > column[next].len) {
return next
}
return prev
})
column[smalColumnNum].len += group[elementName].length + groupHeight
column[smalColumnNum].data.push(group)
})
const prettyColumn = Object.keys(column).map(colNum =>
({ column: colNum, len: column[colNum].len, data: column[colNum].data }))
return prettyColumn
}
function updateGroupColumn(oldColumn, newDataGroup, elementName) {
/*
newDataGroup = [{id: number, value: array},]
console.log(newDataGroup)
*/
const groupMap = newDataGroup.reduce((all, group) => Object.assign(all, { [group.id]: group }), {})
const missingGroup = []
oldColumn.forEach((column) => { // колонка
const isGroup = {}
const updateColumn = column.data.map((group) => { // группа
if (groupMap[group.id]) {
const missingOutcomes = []
const isOutcome = {}
const outcomeMapInGroup = groupMap[group.id][elementName]
.reduce((all, outcome) => Object.assign(all, { [outcome.id]: outcome }), {})
const updateGroup = group[elementName].map((outcome) => { // елемент группы
if (outcomeMapInGroup[outcome.id]) {
isOutcome[outcome.id] = true
return outcomeMapInGroup[outcome.id]
}
return null
}).filter(outcome => outcome !== null)
groupMap[group.id][elementName].forEach((newOutcome) => {
if (!isOutcome[newOutcome.id]) {
missingOutcomes.push(newOutcome)
}
})
const mergeOutcomes = updateGroup.concat(missingOutcomes)
group[elementName] = mergeOutcomes
isGroup[group.id] = true
// console.log('mergeOutcomes', mergeOutcomes)
return group
}
return null
}).filter(group => group !== null)
column.data = updateColumn
column.len = updateColumn.reduce((sum, group) => sum + group[elementName].length, 0)
})
missingGroup.forEach((group, i) => {
const smalColumnNum = Object.keys(oldColumn).reduce((prev, next) => {
if (oldColumn[prev].len > oldColumn[next].len) {
return next
}
return prev
})
// console.log('d', oldColumn[smalColumnNum].data)
oldColumn[smalColumnNum].len += group[elementName].length
oldColumn[smalColumnNum].data = oldColumn[smalColumnNum].data.concat(group)
})
return oldColumn
}
// example ->
const random = (min = 5, max = 15) => {
let rand = min - 0.5 + Math.random() * (max - min + 1)
rand = Math.round(rand)
return rand
}
function createCroupData(len) {
const Items = (id, count) => new Array(count)
.fill(undefined).map((el, i) => ({id: i, k: i, groupId: id}))
const Group = (id, value) => ({ id, value })
// ----- util
const d = []
for (let i = 1; i < len; i++) {
d.push(Group(i, Items(i, random())))
}
return d
}
const d = createCroupData(10)
const updateD = createCroupData(10)
const maxAllCount = data => data.reduce((count, group) =>
count + group.value.length, 0)
console.log('maxAllCount', maxAllCount(d), maxAllCount(updateD))
const column = sortGroupColumn(d, 3, 1, 'value')
const updateColumn = updateGroupColumn(column, updateD, 'value')
const logEach = (data, prop, fn) => data.forEach((el) => {
if (fn) console.log( fn(el[prop]) )
else console.log(el[prop])
})
// <- example
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment