Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Объединение одинаковых значений в столбцах таблицы (https://javascript.ru/forum/dom-window/85700-obedinenie-odinakovykh-znachenijj-v-stolbcakh-tablicy.html)

Anat37 12.01.2024 13:38

Цитата:

Сообщение от Nexus (Сообщение 554437)
Так?
<div id="table-container"></div>

<style>
table, th, td {
  border: 1px solid;
  border-collapse: collapse;
}
</style>

<script>
    function groupBy(iterable, key) {
        const result = {};
        for (let item of iterable) {
            const itemKey = item[key] ?? '';

            result[itemKey] ??= [];
            result[itemKey].push(item);
        }

        return result;
    }

    function makeTableNode(groupedData, groupedByKey) {
        const values = Object.values(groupedData);
        const firstItem = values?.at(0)?.at(0);
        
        const table = document.createElement('table');
        if (!firstItem) {
            return table;
        }
        
        // thead
        const thead = document.createElement('thead');
        table.appendChild(thead);
        
        const tr = document.createElement('tr');
        thead.appendChild(tr);
        
        for (let key in firstItem) {
            const th = document.createElement('th');
            th.textContent = key;
            
            tr.appendChild(th);
        }
        
        // tbody
        const tbody = document.createElement('tbody');
        table.appendChild(tbody);
        
        values?.forEach(list => {
            list.forEach((item, index)=> {
                const tr = document.createElement('tr');
                tbody.appendChild(tr);
                
                for(let key in item) {
                    const isGroupByKey = key === groupedByKey;
                    if (index && isGroupByKey) {
                        continue;
                    }
                    
                    const td = document.createElement('td');
                    tr.appendChild(td);
                    
                    td.textContent = item[key];
                    if (isGroupByKey && list.length) {
                        td.rowSpan = list.length;
                    }
                }
            });
        });
        
        return table;
    }

    var data = [{id:'1',name:'1',fid:''},{id:'2',name:'2',fid:'1'} ,{id:'3',name:'3',fid:''},{id:'4',name:'4',fid:'1' },{id:'5',name:'5',fid:'3'},{id:'6',name:'6',fid:' 3'}];

    (data => {
        const container = document.querySelector('#table-container');
        if (!container) {
            return;
        }
        
        container.innerHTML = '';
        container.appendChild(
            makeTableNode(
                groupBy(data, 'fid'),
                'fid'
            )
        );
    })(data);
</script>

Да, приблизительно так.
Только с пустыми fid не объединять, а строки с fid:'3' - объединить.

voraa 12.01.2024 14:20

<head>
<style>
table {
	border: 1px solid black;
	border-collapse: collapse;
}
td {
	border: 1px solid black;
}
</style>
</head>
<body>
<table id="mytable"></table>
<script>
const data = [
{id:"1", name: "1", fid:""},
{id:"2", name: "2", fid:"1"},
{id:"3", name: "3", fid:"3"},
{id:"4", name: "4", fid:"4"},
{id:"5", name: "5", fid:"1"},
{id:"6", name: "6", fid:""},
{id:"7", name: "7", fid:"5"},
{id:"8", name: "8", fid:""},
{id:"9", name: "9", fid:"3"},
{id:"10", name: "10", fid:"1"},
{id:"11", name: "11", fid:""},
{id:"12", name: "12", fid:"5"}
];

function groupe (data) {
	const groupedata = [];
	for (const {id, name, fid} of data) {
		if (fid === "") {
			groupedata.push({rows:[{id, name}], fid});
		} else {
			const row = groupedata.find(row => row.fid === fid)
			if (!row) {
				groupedata.push({rows:[{id, name}], fid});
			} else {
				row.rows.push({id, name})
			}
		}
	}
	return groupedata;
}

function createtable (table, groupedata) {
	const thead = document.createElement('thead')
	thead.innerHTML = '<tr><th>id</th><th>name</th><th>fid</th></tr>';
	table.append(thead);
	const tbody = document.createElement('tbody');
	for (const {rows, fid} of groupedata) {
		for (let i = 0; i<rows.length; i++) {
			const row = document.createElement('tr');
			const tdid = document.createElement('td');
			const tdname = document.createElement('td');
			tdid.textContent = rows[i].id;
			tdname.textContent = rows[i].name;
			row.append(tdid,tdname);
			if (i === 0) {
				const tdfid = document.createElement('td');
				tdfid.textContent = fid;
				tdfid.rowSpan = rows.length;
				row.append (tdfid)
			}
			tbody.append (row);

		}		
	}
	table.append(tbody);
}

const groupedata = groupe(data);
createtable(document.getElementById('mytable'), groupedata);
</script>
<body>

Anat37 12.01.2024 14:49

Цитата:

Сообщение от voraa
<head>
<style>
table {
    border: 1px solid black;
    border-collapse: collapse;
}
td {
    border: 1px solid black;
}
</style>
</head>

СПАСИБО!!!!!!! ЭТО ТО, ЧТО НАДО!

Плюсик поставил, жаль что нельзя поставить 5.

А можно еще попросить проставить комментарии в какой строке что происходит. Мне хотелось бы не просто скопипастить код, но и самому понять где, что и как, т.к. я хочу научиться сам это делать.

voraa 12.01.2024 14:56

Цитата:

Сообщение от Anat37
А можно еще попросить проставить комментарии в какой строке что происходит.

Позже. Занят. Ухожу.

Anat37 12.01.2024 15:18

Цитата:

Сообщение от voraa (Сообщение 554443)
Позже. Занят. Ухожу.

Ничего страшного, я подожду, мне не горит я просто учусь.
К тому же завтра выходные, заниматься изучением будет некогда.

И еще вопрос:
Я немного изменил массив, оставил только fid:"1" для удобства

const data = [
{id:"2", name: "2", fid:"1"},
{id:"6", name: "2", fid:"1"},
{id:"2", name: "2", fid:"1"},
{id:"7", name: "7", fid:"1"},
{id:"10", name: "10", fid:"1"},
];


столбец fid:"1" получается объединенный, как продолжить объединение ячеек в других столбцах, например где name: "2" и id:"2" ?

соответственно, так же изначально неизвестно количество name: "2" и id:"2"

Если "криво" объяснил, пишите.

Nexus 12.01.2024 17:21

Anat37, если у вас id где-то повторяется, то у вас что-то не так с данными, потому что id предполагается уникальным.

Anat37 12.01.2024 17:26

Цитата:

Сообщение от Nexus (Сообщение 554445)
Anat37, если у вас id где-то повторяется, то у вас что-то не так с данными, потому что id предполагается уникальным.

id - это название

voraa 12.01.2024 18:04

Почему сразу не спросить все то, что нужно.
А то - сначала "для разминки" скажите как сделать то, потом усложним задание, сделайте это.
Спросите сразу все, что надо. Сделайте нормальный тестовый пример, что бы нам его не придумывать...

Anat37 15.01.2024 08:28

Цитата:

Сообщение от voraa (Сообщение 554447)
Почему сразу не спросить все то, что нужно.
А то - сначала "для разминки" скажите как сделать то, потом усложним задание, сделайте это.
Спросите сразу все, что надо. Сделайте нормальный тестовый пример, что бы нам его не придумывать...

Здравствуйте, уважаемый voraa!
1. Извините что сразу не ответил, в выходные занят сильно.
2. Нивкоем разе не хотел никого обидеть, я самостоятельно пытаюсь изучить JS и сам себе придумываю задания. Поэтому так и получилось.Извините еще раз.

Попробую объяснить задачу:
В таблице количество столбцов изначально неизвестно (может быть 1, а может быть и 10). В каждом столбце могут быть одинаковые строки.
Сначала идет объединение по первому столбцу, потом по второму, но объединяются строки, которые входят в объединенные строки первого столбца и т.д..
const data = [
{id:"2", name: "2", fid:"1"},
{id:"6", name: "2", fid:"1"},
{id:"2", name: "2", fid:"1"},
{id:"7", name: "7", fid:"1"},
{id:"10", name: "10", fid:"1"},
{id:"11", name: "11", fid:"2"},
{id:"12", name: "11", fid:"2"},
{id:"1", name: "1", fid:"2"},
{id:"10", name: "10", fid:"2"},
{id:"5", name: "5", fid:""},
{id:"3", name: "5", fid:""},
];


т.е. из этого объединение нет по строке вообще если первый столбец пустой,
{id:"10", name: "10", fid:"1"}, и {id:"10", name: "10", fid:"2"}, объединения по id и name нет, т.к. они в разных объединения первого столбца.
Надеюсь объяснил правильно.
И еще вопрос: можете посоветовать учебное пособие для самостоятельного изучения?
Здесь вот есть похожее, но из таблицы, а не из массива:
https://stackoverflow.com/questions/...ing-javascript

voraa 15.01.2024 09:22

Цитата:

Сообщение от Anat37
Сначала идет объединение по первому столбцу, потом по второму,

Вы столбцы с конца считаете? Обычно считают с начала.
Цитата:

Сообщение от Anat37
можете посоветовать учебное пособие для самостоятельного изучения?

Изучение чего? Если js, то https://learn.javascript.ru/
Цитата:

Сообщение от Anat37
В таблице количество столбцов изначально неизвестно (может быть 1, а может быть и 10). В каждом столбце могут быть одинаковые строки.

В такой постановке это не слишком простая задача


Часовой пояс GMT +3, время: 07:18.