合并两列成一列,保留每个值。

huangapple go评论54阅读模式
英文:

merge two columns into one preserving the values of each

问题

$('.importer').click(function(e){
	e.preventDefault();
	var cols= $(".tbi").find("tr:first th").length-1;
	var intestColonne = [];
	$('.tbi').find('tr:first th > select').each(function(){
		intestColonne.push($(this).val());
	});
	const importi = intestColonne.map((x, i) => x === 'importo' ? i : null).filter(x => x != null);

	var movimenti=[];
	$('.tbi > tbody  > tr').each(function(index, tr) { 
		var movimento = [];
   		$(this).find('td').each(function(index,td){
			if(index<cols){
				var columnName = intestColonne[index];
				if (movimento[columnName] !== undefined) {
					if (Array.isArray(movimento[columnName])) {
						movimento[columnName].push($(this).text());
					} else {
						movimento[columnName] = [movimento[columnName], $(this).text()];
					}
				} else {
					movimento[columnName] = $(this).text();
				}
			}else{
				movimento['causale']= $(this).children('select').val();
				movimento['segno']= $(this).children('select').find(':selected').data('segno');
			}
		});
		movimenti.push(movimento);
	});
	console.log(movimenti);
});
英文:

I have a table that contains some data that I want to put in an array. The table layout can change from time to time and it is up to the user to decide what are the column header for each column (the column header becomes the key in the array. In the table there can be multiple columns with the same header but in that case the data are in one or the ohter column:

all unique

Date Description Amount
First row 100
Second row -50

duplicate header

Date Description Amount Amount
First row 100
Second row -50

Note that the order of the columns is defined by the user depending on the source of the table (a csv he uploaded to my application). The code I have so far works well with unique header and is able to spot the index of the duplicates.
For the duplicate situation the issue is that on row First it will return Amount:'' because it will overwrite the former with the latter. On row Second it will return Amount: '-50' as expected. I need help to improve my code to have row First returning Amount: '100' in the duplicate situation.

My code:

$('.importer').click(function(e){
e.preventDefault();
//quante colonne sono rimaste
var cols= $(".tbi").find("tr:first th").length-1;
//mappatura di ogni colonna
var intestColonne = [];
$('.tbi').find('tr:first th > select').each(function(){
intestColonne.push($(this).val());
});
const importi=intestColonne.map((x, i) => x === 'importo' ? i : null).filter(x => x != null);
//il pezzo commentato fa la stessa cosa della riga sopra
/*intestColonne.reduce((acc, curr, i) => {
if (curr === 'importo') acc.push(i);
console.log(acc);
return acc;
}, []);*/
//leggo ogni colonna
var movimenti=[];
$('.tbi > tbody  > tr').each(function(index, tr) { 
var movimento = [];
$(this).find('td').each(function(index,td){
if(index<cols){
movimento[intestColonne[index]] = $(this).text();
//here I have to add something to manage the duplicate indexes that are stored in the importi const								
}else{
movimento['causale']= $(this).children('select').val();
movimento['segno']= $(this).children('select').find(':selected').data('segno');
}
});
movimenti.push(movimento);
});
console.log(movimenti);
});

The result for Second row will be like this

Array []
​​    causale: "3"
​​    data_cont: "19/01/2021"
​​    data_val: "19/01/2021"
​​    descr: "PRELIEVO BANCOMAT"
​​    importo: "-50"
​​    length: 0
​​    segno: "-"

while actually for row First it will be like

0: Array []
​​    causale: "3"
​​    data_cont: "19/01/2021"
​​    data_val: "19/01/2021"
​​    descr: "PRELIEVO BANCOMAT"
​​    importo: ""
​​    length: 0
​​    segno: "-"

while I'd like to have importo:"100" there

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

$(&#39;.importer&#39;).click(function(e){
e.preventDefault();
//quante colonne sono rimaste
var cols= $(&quot;.tbi&quot;).find(&quot;tr:first th&quot;).length-1;
//mappatura di ogni colonna
var intestColonne = [];
$(&#39;.tbi&#39;).find(&#39;tr:first th &gt; select&#39;).each(function(){
intestColonne.push($(this).val());
});
const importi=intestColonne.map((x, i) =&gt; x === &#39;importo&#39; ? i : null).filter(x =&gt; x != null);
//il pezzo commentato fa la stessa cosa della riga sopra
/*intestColonne.reduce((acc, curr, i) =&gt; {
if (curr === &#39;importo&#39;) acc.push(i);
console.log(acc);
return acc;
}, []);*/
//leggo ogni colonna
var movimenti=[];
$(&#39;.tbi &gt; tbody  &gt; tr&#39;).each(function(index, tr) { 
var movimento = [];
$(this).find(&#39;td&#39;).each(function(index,td){
if(index&lt;cols){
movimento[intestColonne[index]] = $(this).text();								
}else{
movimento[&#39;causale&#39;]= $(this).children(&#39;select&#39;).val();
movimento[&#39;segno&#39;]= $(this).children(&#39;select&#39;).find(&#39;:selected&#39;).data(&#39;segno&#39;);
}
});
movimenti.push(movimento);
});
console.log(movimenti);
});

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;button class=&quot;importer&quot;&gt;create array&lt;/button&gt;
&lt;table class=&quot;tbi&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;select name=&quot;tipo_mov0&quot;&gt;
&lt;option value=&quot;&quot;&gt;Tipo campo&lt;/option&gt;
&lt;option value=&quot;data_val&quot; selected&gt;Data Valuta&lt;/option&gt;
&lt;option value=&quot;data_cont&quot;&gt;Data Cont&lt;/option&gt;
&lt;option value=&quot;descr&quot;&gt;Descrizione&lt;/option&gt;
&lt;option value=&quot;importo&quot;&gt;Importo&lt;/option&gt;
&lt;/select&gt; &lt;i class=&quot;fas fa-trash-alt bin&quot;&gt;&lt;/i&gt;&lt;/th&gt;
&lt;th&gt;&lt;select name=&quot;tipo_mov1&quot;&gt;
&lt;option value=&quot;&quot;&gt;Tipo campo&lt;/option&gt;
&lt;option value=&quot;data_val&quot;&gt;Data Valuta&lt;/option&gt;
&lt;option value=&quot;data_cont&quot; selected&gt;Data Cont&lt;/option&gt;
&lt;option value=&quot;descr&quot;&gt;Descrizione&lt;/option&gt;
&lt;option value=&quot;importo&quot;&gt;Importo&lt;/option&gt;
&lt;/select&gt; &lt;i class=&quot;fas fa-trash-alt bin&quot;&gt;&lt;/i&gt;&lt;/th&gt;
&lt;th&gt;&lt;select name=&quot;tipo_mov2&quot;&gt;
&lt;option value=&quot;&quot;&gt;Tipo campo&lt;/option&gt;
&lt;option value=&quot;data_val&quot;&gt;Data Valuta&lt;/option&gt;
&lt;option value=&quot;data_cont&quot;&gt;Data Cont&lt;/option&gt;
&lt;option value=&quot;descr&quot; selected&gt;Descrizione&lt;/option&gt;
&lt;option value=&quot;importo&quot;&gt;Importo&lt;/option&gt;
&lt;/select&gt; &lt;i class=&quot;fas fa-trash-alt bin&quot;&gt;&lt;/i&gt;&lt;/th&gt;
&lt;th&gt;&lt;select name=&quot;tipo_mov4&quot;&gt;
&lt;option value=&quot;&quot;&gt;Tipo campo&lt;/option&gt;
&lt;option value=&quot;data_val&quot;&gt;Data Valuta&lt;/option&gt;
&lt;option value=&quot;data_cont&quot;&gt;Data Cont&lt;/option&gt;
&lt;option value=&quot;descr&quot;&gt;Descrizione&lt;/option&gt;
&lt;option value=&quot;importo&quot; selected&gt;Importo&lt;/option&gt;
&lt;/select&gt; &lt;i class=&quot;fas fa-trash-alt bin&quot;&gt;&lt;/i&gt;&lt;/th&gt;
&lt;th&gt;&lt;select name=&quot;tipo_mov5&quot;&gt;
&lt;option value=&quot;&quot;&gt;Tipo campo&lt;/option&gt;
&lt;option value=&quot;data_val&quot;&gt;Data Valuta&lt;/option&gt;
&lt;option value=&quot;data_cont&quot;&gt;Data Cont&lt;/option&gt;
&lt;option value=&quot;descr&quot;&gt;Descrizione&lt;/option&gt;
&lt;option value=&quot;importo&quot; selected&gt;Importo&lt;/option&gt;
&lt;/select&gt; &lt;i class=&quot;fas fa-trash-alt bin&quot;&gt;&lt;/i&gt;&lt;/th&gt;
&lt;th&gt;Causale&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;19/01/2021&lt;/td&gt;
&lt;td&gt;19/01/2021&lt;/td&gt;
&lt;td&gt;PRELIEVO BANCOMAT&lt;/td&gt;
&lt;td&gt;250.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;19/01/2021&lt;/td&gt;
&lt;td&gt;16/01/2021&lt;/td&gt;
&lt;td&gt;PAGAMENTO POS &lt;/td&gt;
&lt;td&gt;60.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;19/01/2021&lt;/td&gt;
&lt;td&gt;16/01/2021&lt;/td&gt;
&lt;td&gt;PAGAMENTO POS &lt;/td&gt;
&lt;td&gt;42.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;15/01/2021&lt;/td&gt;
&lt;td&gt;15/01/2021&lt;/td&gt;
&lt;td&gt;ADDEBITO SDD&lt;/td&gt;
&lt;td&gt;1501.2&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;15/01/2021&lt;/td&gt;
&lt;td&gt;13/01/2021&lt;/td&gt;
&lt;td&gt;PAGAMENTO POS &lt;/td&gt;
&lt;td&gt;167.31&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;11/01/2021&lt;/td&gt;
&lt;td&gt;06/01/2021&lt;/td&gt;
&lt;td&gt;PAGAMENTO UTENZE&lt;/td&gt;
&lt;td&gt;20.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;08/01/2021&lt;/td&gt;
&lt;td&gt;05/01/2021&lt;/td&gt;
&lt;td&gt;PAGAMENTO POS &lt;/td&gt;
&lt;td&gt;7.88&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;07/01/2021&lt;/td&gt;
&lt;td&gt;06/01/2021&lt;/td&gt;
&lt;td&gt;PRELIEVO BANCOMAT&lt;/td&gt;
&lt;td&gt;250.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;05/01/2021&lt;/td&gt;
&lt;td&gt;05/01/2021&lt;/td&gt;
&lt;td&gt;BONIFICO&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;900.0&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

<!-- end snippet -->

If you run the above snippet you will end up that only the last row will have a value for "Importo". All the other will have nothing. 250.0 in the first row will be overwritten by the second "Importo" column that is empty

答案1

得分: 1

根据我的理解,当你移动到下一个单元格时,你想获取单元格的文本值,除非它是空的,而且已经存在一个非空的抓取值用于此标题。
因此,这行代码

movimento[intestColonne[index]] = $(this).text();

应该变成

var oldText = movimento[intestColonne[index]];
var newText = $(this).text();
if (newText || !oldText) movimento[intestColonne[index]] = newText;
英文:

From my understanding, when you move to next cell, you want to grab the cell text value UNLESS it is empty and there is already a non empty grabbed value for this header.
So, the line

movimento[intestColonne[index]] = $(this).text();

should become

var oldText = movimento[intestColonne[index]];
var newText = $(this).text();
if (newText || !oldText) movimento[intestColonne[index]] = newText;

答案2

得分: 0

请不要误会,但我对你的解释仍然有困难。尽管如此,我编写了这段代码,希望能帮助你。

const
  TbHead = document.querySelector('table.tbi thead'),
  TbBody = document.querySelector('table.tbi tbody');
btMergeCols.onclick = () => {
  let cols = [...TbHead.querySelectorAll('th select[name^="tipo_mov"]')]
    .map(selec => ({ lib: selec.value, col: selec.closest('th').cellIndex, smovN: selec.name }))
    .sort((a, b) => b.lib.localeCompare(a.lib) || b.col - a.col); // 简化测试顺序。

  cols.forEach((curElm, i, { [i + 1]: nxtElm }) => {
    if (!!nxtElm && curElm.lib === nxtElm.lib) {
      TbHead.rows[0].deleteCell(nxtElm.col);
      console.log(`${curElm.smovN} (${curElm.lib}) is removed (duplicate)`);

      for (let r = 0; r < TbBody.rows.length; r++) {
        let CurVal = TbBody.rows[r].cells[curElm.col].textContent.trim();

        if (CurVal !== '')
          TbBody.rows[r].cells[nxtElm.col].textContent = CurVal;

        TbBody.rows[r].deleteCell(curElm.col);
      }
    }
  });

  // 创建数组部分
  let movimenti = [],
    finalCols = [...TbHead.querySelectorAll('th select[name^="tipo_mov"]')]
      .map(selec => ({ lib: selec.value, col: selec.closest('th').cellIndex }));
  [...TbBody.rows].forEach(row => {
    let elm = {};
    movimenti.push(elm);
    finalCols.forEach(({ lib, col }) => {
      elm[lib] = row.cells[col].textContent.trim();
    });
  });

  console.log(JSON.stringify(movimenti, 0, 2));
};
body {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 14px;
  margin: 1rem;
}
table {
  border-collapse: separate;
  border-spacing: 1px;
  background-color: lightslategrey;
}
tr {
  background-color: cadetblue;
}
td {
  background-color: whitesmoke;
  padding: .2em .5em;
}
<button id="btMergeCols">合并重复列 / 创建数组</button><br><br>

<table class="tbi">
  <thead>
    <tr>
      <th>
        <select name="tipo_mov0">
          <option value="">Tipo campo</option>
          <option value="data_val" selected>Data Valuta</option>
          <option value="data_cont">Data Cont</option>
          <option value="descr">Descrizione</option>
          <option value="importo">Importo</option>
        </select> <i class="fas fa-trash-alt bin"></i></th>
      <th>
        <select name="tipo_mov1">
          <option value="">Tipo campo</option>
          <option value="data_val">Data Valuta</option>
          <option value="data_cont" selected>Data Cont</option>
          <option value="descr">Descrizione</option>
          <option value="importo">Importo</option>
        </select> <i class="fas fa-trash-alt bin"></i></th>
      <th>
        <select name="tipo_mov2">
          <option value="">Tipo campo</option>
          <option value="data_val">Data Valuta</option>
          <option value="data_cont">Data Cont</option>
          <option value="descr" selected>Descrizione</option>
          <option value="importo">Importo</option>
        </select> <i class="fas fa-trash-alt bin"></i></th>
      <th>
        <select name="tipo_mov4">
          <option value="">Tipo campo</option>
          <option value="data_val">Data Valuta</option>
          <option value="data_cont">Data Cont</option>
          <option value="descr">Descrizione</option>
          <option value="importo" selected>Importo</option>
        </select> <i class="fas fa-trash-alt bin"></i></th>
      <th>
        <select name="tipo_mov5">
          <option value="">Tipo campo</option>
          <option value="data_val">Data Valuta</option>
          <option value="data_cont">Data Cont</option>
          <option value="descr">Descrizione</option>
          <option value="importo" selected>Importo</option>
        </select> <i class="fas fa-trash-alt bin"></i></th>
      <th>Causale</th>
    </tr>
  </thead>
  <tbody>
    <!-- 此处省略了表格数据,因为内容较多 -->
  </tbody>
</table>
英文:

Don't take this the wrong way, but I still have trouble with your explanations.
I nevertheless wrote this piece of code which I hope will help you (?)

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const
TbHead = document.querySelector(&#39;table.tbi thead&#39;)
, TbBody = document.querySelector(&#39;table.tbi tbody&#39;)
;
btMergeCols.onclick =_=&gt;
{
let cols = [...TbHead.querySelectorAll(&#39;th select[name^=&quot;tipo_mov&quot;]&#39; )]
.map( selec =&gt; ({ lib:selec.value, col: selec.closest(&#39;th&#39;).cellIndex, smovN: selec.name }))
.sort( (a,b)=&gt; b.lib.localeCompare(a.lib) || b.col-a.col); // simplify test order.
//console.log( JSON.stringify(cols,0,2)); 
cols.forEach( (curElm,i,{[i+1]:nxtElm}) =&gt; 
{
if (!!nxtElm &amp;&amp; curElm.lib===nxtElm.lib )
{
TbHead.rows[0].deleteCell(nxtElm.col);     console.log( `${curElm.smovN} (${curElm.lib}) is removed (duplicate)` );
for (let r = 0; r &lt; TbBody.rows.length; r++) 
{
let CurVal = TbBody.rows[ r ].cells[ curElm.col ].textContent.trim();
if (CurVal !== &#39;&#39;)
TbBody.rows[ r ].cells[ nxtElm.col ].textContent = CurVal;
TbBody.rows[r].deleteCell(curElm.col);
}
}
})
// create array part
let movimenti = []
, finalCols = [...TbHead.querySelectorAll(&#39;th select[name^=&quot;tipo_mov&quot;]&#39; )]
.map( selec =&gt; ({ lib:selec.value, col: selec.closest(&#39;th&#39;).cellIndex }))
;
[...TbBody.rows].forEach( row =&gt; 
{
let elm = {};
movimenti.push(elm);
finalCols.forEach( ({lib,col})=&gt;
{
elm[lib] = row.cells[col].textContent.trim();
});
});
console.log( JSON.stringify(movimenti,0,2 ));
}

<!-- language: lang-css -->

body {
font-family : Arial, Helvetica, sans-serif;
font-size   : 14px;
margin      : 1rem;
}
table {
border-collapse  : separate;
border-spacing   : 1px;
background-color : lightslategrey;
}
tr { background-color: cadetblue;  }
td { background-color: whitesmoke; padding: .2em .5em; }

<!-- language: lang-html -->

&lt;button id=&quot;btMergeCols&quot;&gt; merge duplicates columns / create array &lt;/button&gt;
&lt;br&gt;&lt;br&gt;
&lt;table class=&quot;tbi&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;
&lt;select name=&quot;tipo_mov0&quot;&gt;
&lt;option value=&quot;&quot;&gt;Tipo campo&lt;/option&gt;
&lt;option value=&quot;data_val&quot; selected&gt;Data Valuta&lt;/option&gt;
&lt;option value=&quot;data_cont&quot;&gt;Data Cont&lt;/option&gt;
&lt;option value=&quot;descr&quot;&gt;Descrizione&lt;/option&gt;
&lt;option value=&quot;importo&quot;&gt;Importo&lt;/option&gt;
&lt;/select&gt; &lt;i class=&quot;fas fa-trash-alt bin&quot;&gt;&lt;/i&gt;&lt;/th&gt;
&lt;th&gt;
&lt;select name=&quot;tipo_mov1&quot;&gt;
&lt;option value=&quot;&quot;&gt;Tipo campo&lt;/option&gt;
&lt;option value=&quot;data_val&quot;&gt;Data Valuta&lt;/option&gt;
&lt;option value=&quot;data_cont&quot; selected&gt;Data Cont&lt;/option&gt;
&lt;option value=&quot;descr&quot;&gt;Descrizione&lt;/option&gt;
&lt;option value=&quot;importo&quot;&gt;Importo&lt;/option&gt;
&lt;/select&gt; &lt;i class=&quot;fas fa-trash-alt bin&quot;&gt;&lt;/i&gt;&lt;/th&gt;
&lt;th&gt;
&lt;select name=&quot;tipo_mov2&quot;&gt;
&lt;option value=&quot;&quot;&gt;Tipo campo&lt;/option&gt;
&lt;option value=&quot;data_val&quot;&gt;Data Valuta&lt;/option&gt;
&lt;option value=&quot;data_cont&quot;&gt;Data Cont&lt;/option&gt;
&lt;option value=&quot;descr&quot; selected&gt;Descrizione&lt;/option&gt;
&lt;option value=&quot;importo&quot;&gt;Importo&lt;/option&gt;
&lt;/select&gt; &lt;i class=&quot;fas fa-trash-alt bin&quot;&gt;&lt;/i&gt;&lt;/th&gt;
&lt;th&gt;
&lt;select name=&quot;tipo_mov4&quot;&gt;
&lt;option value=&quot;&quot;&gt;Tipo campo&lt;/option&gt;
&lt;option value=&quot;data_val&quot;&gt;Data Valuta&lt;/option&gt;
&lt;option value=&quot;data_cont&quot;&gt;Data Cont&lt;/option&gt;
&lt;option value=&quot;descr&quot;&gt;Descrizione&lt;/option&gt;
&lt;option value=&quot;importo&quot; selected&gt;Importo&lt;/option&gt;
&lt;/select&gt; &lt;i class=&quot;fas fa-trash-alt bin&quot;&gt;&lt;/i&gt;&lt;/th&gt;
&lt;th&gt;
&lt;select name=&quot;tipo_mov5&quot;&gt;
&lt;option value=&quot;&quot;&gt;Tipo campo&lt;/option&gt;
&lt;option value=&quot;data_val&quot;&gt;Data Valuta&lt;/option&gt;
&lt;option value=&quot;data_cont&quot;&gt;Data Cont&lt;/option&gt;
&lt;option value=&quot;descr&quot;&gt;Descrizione&lt;/option&gt;
&lt;option value=&quot;importo&quot; selected&gt;Importo&lt;/option&gt;
&lt;/select&gt; &lt;i class=&quot;fas fa-trash-alt bin&quot;&gt;&lt;/i&gt;&lt;/th&gt;
&lt;th&gt;Causale&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;19/01/2021&lt;/td&gt;
&lt;td&gt;19/01/2021&lt;/td&gt;
&lt;td&gt;PRELIEVO BANCOMAT&lt;/td&gt;
&lt;td&gt;250.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;
&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;19/01/2021&lt;/td&gt;
&lt;td&gt;16/01/2021&lt;/td&gt;
&lt;td&gt;PAGAMENTO POS &lt;/td&gt;
&lt;td&gt;60.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;
&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;19/01/2021&lt;/td&gt;
&lt;td&gt;16/01/2021&lt;/td&gt;
&lt;td&gt;PAGAMENTO POS &lt;/td&gt;
&lt;td&gt;42.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;
&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;15/01/2021&lt;/td&gt;
&lt;td&gt;15/01/2021&lt;/td&gt;
&lt;td&gt;ADDEBITO SDD&lt;/td&gt;
&lt;td&gt;1501.2&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;
&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;15/01/2021&lt;/td&gt;
&lt;td&gt;13/01/2021&lt;/td&gt;
&lt;td&gt;PAGAMENTO POS &lt;/td&gt;
&lt;td&gt;167.31&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;
&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;11/01/2021&lt;/td&gt;
&lt;td&gt;06/01/2021&lt;/td&gt;
&lt;td&gt;PAGAMENTO UTENZE&lt;/td&gt;
&lt;td&gt;20.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;
&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;08/01/2021&lt;/td&gt;
&lt;td&gt;05/01/2021&lt;/td&gt;
&lt;td&gt;PAGAMENTO POS &lt;/td&gt;
&lt;td&gt;7.88&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;
&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;07/01/2021&lt;/td&gt;
&lt;td&gt;06/01/2021&lt;/td&gt;
&lt;td&gt;PRELIEVO BANCOMAT&lt;/td&gt;
&lt;td&gt;250.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;
&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;text-info&quot;&gt;
&lt;td&gt;05/01/2021&lt;/td&gt;
&lt;td&gt;05/01/2021&lt;/td&gt;
&lt;td&gt;BONIFICO&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;900.0&lt;/td&gt;
&lt;td class=&quot;text-danger&quot;&gt;
&lt;select name=&quot;causali&quot;&gt;
&lt;option value=&quot;&quot;&gt;Scegli&lt;/option&gt;
&lt;option value=&quot;1&quot; data-segno=&quot;+&quot;&gt;Stipendio&lt;/option&gt;
&lt;option value=&quot;2&quot; data-segno=&quot;-&quot;&gt;Rata Mutuo&lt;/option&gt;
&lt;option value=&quot;3&quot; data-segno=&quot;-&quot;&gt;Saldo carta di credito&lt;/option&gt;
&lt;option value=&quot;4&quot; data-segno=&quot;+&quot;&gt;Interessi Attivi&lt;/option&gt;
&lt;option value=&quot;5&quot; data-segno=&quot;-&quot;&gt;Interessi Passivi&lt;/option&gt;
&lt;option value=&quot;9&quot; data-segno=&quot;-&quot;&gt;Spese banca&lt;/option&gt;
&lt;option value=&quot;10&quot; data-segno=&quot;-&quot;&gt;giro a c/famiglia&lt;/option&gt;
&lt;/select&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

<!-- end snippet -->

答案3

得分: 0

我自己找到了解决方案:

$(this).find('td').each(function(index, td){
    if(index < cols){
        if(importi.includes(index)){
            if($(this).text() != ''){
                movimento[intestColonne[index]] = $(this).text();
            }
        }else{
            movimento[intestColonne[index]] = $(this).text();
        }
    }else{
        movimento['causale'] = $(this).children('select').val();
        movimento['segno'] = $(this).children('select').find(':selected').data('segno');
    }
});

如果我在被标记为“Importo”的列之一,并且单元格不为空,那么我会推送该值。否则,我将跳过该单元格。我之前就有这个想法,但在代码中无法表达出来。

英文:

I spotted the solution by myself:

$(this).find(&#39;td&#39;).each(function(index,td){
if(index&lt;cols){
if(importi.includes(index)){
if($(this).text()!=&#39;&#39;){
movimento[intestColonne[index]] = $(this).text();
}
}else{
movimento[intestColonne[index]] = $(this).text();
}
}else{
movimento[&#39;causale&#39;]= $(this).children(&#39;select&#39;).val();
movimento[&#39;segno&#39;]= $(this).children(&#39;select&#39;).find(&#39;:selected&#39;).data(&#39;segno&#39;);
}
});

If I am on one of the columns marked as "Importo" if(importi.includes(index)){ and the cell is not empty if($(this).text()!=&#39;&#39;){ then I push the value. Otherwise I will skip the cell. I had this in mind but was not able to write it on code before.

huangapple
  • 本文由 发表于 2023年2月8日 22:27:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75387214.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定