DAWorkbench 0.0.1
DAWorkbench API
载入中...
搜索中...
未找到
DARowTable.hpp
1#ifndef DAROWTABLE_H
2#define DAROWTABLE_H
3// std
4#include <memory>
5// DA
6#include "da_algorithm.hpp"
7#include "DAVector.hpp"
8// Qt
9#include <QDebug>
10namespace DA
11{
12
13//==============================================================
14// DARowTable
15//==============================================================
52template< typename T >
54{
55public:
66 typedef T Type;
67 typedef DAVector< T > SeriesType;
68 typedef std::shared_ptr< SeriesType > SeriesPtr;
69 typedef typename DAVector< T >::iterator SeriesIterator;
70 typedef typename DAVector< T >::const_iterator SeriesConstIterator;
71 typedef DARowTable< T > TableType;
72 typedef std::shared_ptr< TableType > TablePtr;
73
74 static SeriesPtr makeSeries();
75 static SeriesPtr makeSeries(const QString& n);
76 static SeriesPtr makeSeries(std::initializer_list< T > args);
77 static TablePtr makeTable();
78
79 DARowTable();
80 DARowTable(int rows, int columns);
81 void resize(int r, int c);
82 void reserve(int size);
83 //判断是否存在field
84 bool haveFieldid(const QString& field) const;
85
90 void fill(const T& v);
91 const T& at(int r, int c) const;
92 T& at(int r, int c);
93
94 T cell(int r, int c) const;
95 SeriesPtr appendRow(const QString& name);
96 SeriesPtr appendRow(const QString& name, int size);
97 void appendRow(SeriesPtr row);
98 void appendRow(std::initializer_list< T > args, const QString& n);
99
100 template< typename Ite1, typename Ite2 >
101 void appendColumn(Ite1 b, Ite2 e);
102 void appendColumn(std::initializer_list< T > args);
103 int nameToIndex(const QString& n) const;
104 SeriesPtr& row(int r);
105 const SeriesPtr& row(int r) const;
106 SeriesPtr& row(const QString& n);
107 const SeriesPtr& row(const QString& n) const;
108
109 //返回一列数据,返回一个SeriesPtr,这个seriesPtr的写操作不会影响table
110 SeriesPtr colunm(int c) const;
111
112 SeriesType& operator[](int r);
113 const SeriesType& operator[](int r) const;
114 SeriesType& operator[](const QString& rowname);
115 const SeriesType& operator[](const QString& rowname) const;
116
120 void fixSize();
121
126 int rowCount() const;
127
132 int columnCount() const;
133
138 void setMode(Mode m);
139
144 Mode getMode() const;
145
149 void clear();
150
151 void setName(const QString& n);
152 QString getName() const;
153
158 QStringList rowNames() const;
159
164 void setRowNames(const QStringList& ns);
165
173 TablePtr takeByValue(const QString& field, T value) const;
174
181 QPair< QList< TablePtr >, QList< T > > groupBy(const QString& field) const;
182
187 void orderBy(const QString& sn);
188 void orderBy(int rindex);
189
196 QPair< T, int > lowerBound(const T& v, const QString& sortedfield) const;
197 QPair< T, int > lowerBound(const T& v, int r) const;
198 QPair< T, int > upperBound(const T& v, const QString& sortedfield) const;
199 QPair< T, int > upperBound(const T& v, int r) const;
200
206
211 bool isCaseSensitivity() const;
212 //移除
213 void remove(const QString& name);
214 void remove(int rindex);
215
216private:
218 size_t m_columns;
219 Mode m_mode;
220 SeriesPtr m_nullseries;
221 CaseSensitivity m_caseSensitivity;
222};
223
224//==============================================================
225// 全局函数
226//==============================================================
227
228template< typename T >
229typename DARowTable< T >::TablePtr takeByValue(const DARowTable< T >& table, const QString& field, T value)
230{
231 const int r = table.nameToIndex(field);
232
233 typename DARowTable< T >::TablePtr res = DARowTable< T >::makeTable();
234
235 res->setName(table.getName());
236 res->setRowNames(table.rowNames());
237 int csize = table.columnCount();
238
239 for (int i = 0; i < csize; ++i) {
240 if (table.cell(r, i) == value) {
241 typename DARowTable< T >::SeriesPtr col = table.colunm(i);
242 res->appendColumn(col->begin(), col->end());
243 }
244 }
245 return (res);
246}
247
255template< typename T >
256typename DARowTable< T >::TablePtr takeByValue(const DARowTable< T >& table, int r, T value)
257{
258 typename DARowTable< T >::TablePtr res = DARowTable< T >::makeTable();
259
260 res->setName(table.getName());
261 res->setRowNames(table.rowNames());
262 int csize = table.columnCount();
263
264 for (int i = 0; i < csize; ++i) {
265 if (table.cell(r, i) == value) {
266 typename DARowTable< T >::SeriesPtr col = table.colunm(i);
267 res->appendColumn(col->begin(), col->end());
268 }
269 }
270 return (res);
271}
272
279template< typename T >
280QPair< QList< typename DARowTable< T >::TablePtr >, QList< T > > groupby(const DARowTable< T >& table, const QString& field)
281{
282 QList< typename DARowTable< T >::TablePtr > restables;
283 QList< T > gr;
284
285 int rindex = table.nameToIndex(field);
286
287 Q_ASSERT_X(rindex >= 0, "groupby", "unknow field");
288 typename DARowTable< T >::SeriesPtr r = table.row(rindex);
289 if (r == nullptr) {
290 return (qMakePair(restables, gr));
291 }
292 gr = r->toList().toSet().toList();
293 std::sort(gr.begin(), gr.end());
294 for (T v : gr) {
295 restables.append(takeByValue(table, rindex, v));
296 }
297 return (qMakePair(restables, gr));
298}
299
300//==============================================================
301// ValueWithIndex
302//==============================================================
303
304template< typename T >
306{
307public:
308 ValueWithIndex() : index(-1)
309 {
310 }
311
312 ValueWithIndex(const T& v, int i) : value(v), index(i)
313 {
314 }
315
316 T value;
317 int index;
318};
319
320template< typename T >
321bool operator<(const ValueWithIndex< T >& a, const ValueWithIndex< T >& b)
322{
323 return (a.value < b.value);
324}
325
331template< typename T >
332std::shared_ptr< DAVector< ValueWithIndex< T > > > makeIndexSeries(const typename DARowTable< T >::SeriesPtr& p)
333{
334 std::shared_ptr< DAVector< ValueWithIndex< T > > > res = std::make_shared< DAVector< ValueWithIndex< T > > >();
335
336 res->setName(p->getName());
337 const int s = p->size();
338
339 res->reserve(s);
340 for (int i = 0; i < s; ++i) {
341 res->push_back(ValueWithIndex< T >(p->at(i), i));
342 }
343 return (res);
344}
345
346template< typename T >
347void orderBy(DARowTable< T >& table, const QString& field)
348{
349 const int r = table.nameToIndex(field);
350
351 orderBy(table, r);
352}
353
354template< typename T >
355void orderBy(DARowTable< T >& table, int r)
356{
357 typename DARowTable< T >::SeriesPtr row = table.row(r);
358 Q_ASSERT_X(row != nullptr, "orderBy", "unknow field");
359 auto ordser = makeIndexSeries< T >(row);
360
361 std::sort(ordser->begin(), ordser->end());
362 int rowcount = table.rowCount();
363
364 //开始逐一转换
365 for (int rc = 0; rc < rowcount; ++rc) {
366 typename DARowTable< T >::SeriesPtr series = table.row(rc);
367 typename DARowTable< T >::SeriesPtr ns = DARowTable< T >::makeSeries(series->getName());
368 ns->reserve(series->size());
369 for (auto i = ordser->begin(); i != ordser->end(); ++i) {
370 ns->push_back(series->at((*i).index));
371 }
372 table.row(rc).swap(ns);
373 }
374}
375
376//==============================================================
377// DARowTable
378//==============================================================
379
380template< typename T >
381DARowTable< T >::DARowTable() : m_columns(0), m_mode(FixedMode), m_caseSensitivity(CaseInsensitive)
382{
383}
384
385template< typename T >
386DARowTable< T >::DARowTable(int rows, int columns) : m_mode(FixedMode), m_caseSensitivity(CaseInsensitive)
387{
388 m_d.clear();
389 m_d.reserve(rows);
390 for (int i = 0; i < rows; ++i) {
391 m_d.push_back(SeriesType(columns));
392 }
393 m_columns = columns;
394}
395
401template< typename T >
402void DARowTable< T >::resize(int r, int c)
403{
404 m_d.resize(r);
405 for (SeriesPtr& row : m_d) {
406 if (row == nullptr) {
407 row = makeSeries();
408 }
409 row->resize(c);
410 }
411 m_columns = c;
412}
413
419template< typename T >
420bool DARowTable< T >::haveFieldid(const QString& field) const
421{
422 int r = rowCount();
423 Qt::CaseSensitivity cs = isCaseSensitivity() ? Qt::CaseSensitive : Qt::CaseInsensitive;
424
425 for (int i = 0; i < r; ++i) {
426 if (row(i)->name().compare(field, cs) == 0) {
427 return (true);
428 }
429 }
430 return (false);
431}
432
433template< typename T >
434void DARowTable< T >::fill(const T& v)
435{
436 for (SeriesPtr r : m_d) {
437 r->fill(v);
438 }
439}
440
441template< typename T >
442const T& DARowTable< T >::at(int r, int c) const
443{
444 return (m_d.at(r)->at(c));
445}
446
447template< typename T >
448T& DARowTable< T >::at(int r, int c)
449{
450 return (m_d[ r ]->operator[](c));
451}
452
459template< typename T >
460T DARowTable< T >::cell(int r, int c) const
461{
462 if (r < m_d.size()) {
463 const SeriesPtr& rr = row(r);
464 if (c < rr->size()) {
465 return (rr->at(c));
466 }
467 }
468 return (T());
469}
470
471template< typename T >
472typename DARowTable< T >::SeriesPtr DARowTable< T >::appendRow(const QString& name)
473{
474 return appendRow(name, columnCount());
475}
476
477template< typename T >
478typename DARowTable< T >::SeriesPtr DARowTable< T >::appendRow(const QString& name, int size)
479{
480 SeriesPtr s = makeSeries(name);
481 s->resize(size);
482 appendRow(s);
483 return s;
484}
485
486template< typename T >
487void DARowTable< T >::appendRow(SeriesPtr row)
488{
489 size_t s = row->size();
490
491 if ((s == m_columns) || (0 == m_columns)) {
492 m_d.push_back(row);
493 m_columns = s;
494 } else if (s < m_columns) { //在结尾补充
495 row->resize(m_columns);
496 m_d.push_back(row);
497 } else { // s>m_columns
498 if (getMode() == ExpandMode) {
499 m_d.push_back(row);
500 fixSize();
501 } else {
502 //固定模式的插入
503 row->resize(m_columns);
504 m_d.push_back(row);
505 }
506 }
507}
508
509template< typename T >
510void DARowTable< T >::appendRow(std::initializer_list< T > args, const QString& n)
511{
512 SeriesPtr r = makeSeries(args);
513
514 r->setName(n);
515 appendRow(r);
516}
517
518template< typename T >
519template< typename Ite1, typename Ite2 >
520void DARowTable< T >::appendColumn(Ite1 b, Ite2 e)
521{
522 const int rc = rowCount();
523 auto it = b;
524
525 for (int i = 0; i < rc; ++i) {
526 it = b + i;
527 if (it < e) {
528 row(i)->push_back(*it);
529 } else {
530 row(i)->push_back(T());
531 }
532 }
533 ++m_columns;
534}
535
536template< typename T >
537void DARowTable< T >::appendColumn(std::initializer_list< T > args)
538{
539 const int rc = rowCount();
540
541 for (int i = 0; i < rc; ++i) {
542 if (i < args.size()) {
543 row(i)->push_back(args[ i ]);
544 } else {
545 row(i)->push_back(T());
546 }
547 }
548 ++m_columns;
549}
550
551template< typename T >
552typename DARowTable< T >::SeriesPtr DARowTable< T >::makeSeries(const QString& n)
553{
554 return (std::make_shared< SeriesType >(n));
555}
556
557template< typename T >
558typename DARowTable< T >::SeriesPtr DARowTable< T >::makeSeries(std::initializer_list< T > args)
559{
560 return (std::make_shared< SeriesType >(args));
561}
562
563template< typename T >
564typename DARowTable< T >::TablePtr DARowTable< T >::makeTable()
565{
566 return (std::make_shared< typename DARowTable< T >::TableType >());
567}
568
569template< typename T >
570typename DARowTable< T >::SeriesPtr DARowTable< T >::makeSeries()
571{
572 return (std::make_shared< SeriesType >());
573}
574
575template< typename T >
576int DARowTable< T >::nameToIndex(const QString& n) const
577{
578 int r = rowCount();
579 Qt::CaseSensitivity cs = isCaseSensitivity() ? Qt::CaseSensitive : Qt::CaseInsensitive;
580
581 for (int i = 0; i < r; ++i) {
582 if (row(i)->name().compare(n, cs) == 0) {
583 return (i);
584 }
585 }
586 return (-1);
587}
588
594template< typename T >
595typename DARowTable< T >::SeriesPtr& DARowTable< T >::row(int r)
596{
597 return (m_d[ r ]);
598}
599
605template< typename T >
606const typename DARowTable< T >::SeriesPtr& DARowTable< T >::row(int r) const
607{
608 return (m_d[ r ]);
609}
610
611template< typename T >
612typename DARowTable< T >::SeriesPtr& DARowTable< T >::row(const QString& n)
613{
614 int r = nameToIndex(n);
615
616 if ((r < 0) || (r > rowCount())) {
617 return (m_nullseries);
618 }
619 return (row(r));
620}
621
622template< typename T >
623const typename DARowTable< T >::SeriesPtr& DARowTable< T >::row(const QString& n) const
624{
625 int r = nameToIndex(n);
626
627 if ((r < 0) || (r > rowCount())) {
628 return (m_nullseries);
629 }
630 return (row(r));
631}
632
633template< typename T >
634typename DARowTable< T >::SeriesPtr DARowTable< T >::colunm(int c) const
635{
636 int rsize = rowCount();
637 SeriesPtr col = std::make_shared< SeriesType >(rsize);
638
639 for (int r = 0; r < rsize; ++r) {
640 col->operator[](r) = cell(r, c);
641 }
642 return (col);
643}
644
645template< typename T >
646typename DARowTable< T >::SeriesType& DARowTable< T >::operator[](int r)
647{
648 return (*(row(r)));
649}
650
651template< typename T >
652const typename DARowTable< T >::SeriesType& DARowTable< T >::operator[](int r) const
653{
654 return (*(row(r)));
655}
656
657template< typename T >
658typename DARowTable< T >::SeriesType& DARowTable< T >::operator[](const QString& rowname)
659{
660 return (*(row(rowname)));
661}
662
663template< typename T >
664const typename DARowTable< T >::SeriesType& DARowTable< T >::operator[](const QString& rowname) const
665{
666 return (*(row(rowname)));
667}
668
669template< typename T >
670void DARowTable< T >::reserve(int size)
671{
672 for (SeriesPtr p : m_d) {
673 p->reserve(size);
674 }
675}
676
677template< typename T >
679{
680 std::vector< int > ss;
681
682 for (const SeriesPtr& r : m_d) {
683 ss.push_back(r->size());
684 }
685 int maxsize = *(std::max_element(ss.begin(), ss.end()));
686
687 for (SeriesPtr& r : m_d) {
688 if (r->size() < maxsize) {
689 r->resize(maxsize);
690 }
691 }
692 m_columns = maxsize;
693}
694
695template< typename T >
697{
698 return (m_d.size());
699}
700
701template< typename T >
703{
704 return (m_columns);
705}
706
707template< typename T >
709{
710 m_mode = m;
711}
712
713template< typename T >
715{
716 return (m_mode);
717}
718
719template< typename T >
721{
722 m_d.clear();
723 m_columns = 0;
724}
725
726template< typename T >
727void DARowTable< T >::setName(const QString& n)
728{
729 m_d.setName(n);
730}
731
732template< typename T >
733QString DARowTable< T >::getName() const
734{
735 return (m_d.getName());
736}
737
738template< typename T >
739QStringList DARowTable< T >::rowNames() const
740{
741 QStringList r;
742
743 for (SeriesPtr p : m_d) {
744 r.append(p->getName());
745 }
746 return (r);
747}
748
749template< typename T >
750void DARowTable< T >::setRowNames(const QStringList& ns)
751{
752 const int s = ns.size();
753
754 for (int i = 0; i < s; ++i) {
755 if (i < rowCount()) {
756 row(i)->setName(ns[ i ]);
757 }
758 }
759}
760
761template< typename T >
762typename DARowTable< T >::TablePtr DARowTable< T >::takeByValue(const QString& field, T value) const
763{
764 return (DA::takeByValue(*this, field, value));
765}
766
767template< typename T >
768QPair< QList< typename DARowTable< T >::TablePtr >, QList< T > > DARowTable< T >::groupBy(const QString& field) const
769{
770 return (DA::groupby(*this, field));
771}
772
773template< typename T >
774void DARowTable< T >::orderBy(const QString& sn)
775{
776 DA::orderBy(*this, sn);
777}
778
779template< typename T >
780void DARowTable< T >::orderBy(int rindex)
781{
782 DA::orderBy(*this, rindex);
783}
784
785template< typename T >
786QPair< T, int > DARowTable< T >::lowerBound(const T& v, const QString& sortedfield) const
787{
788 const int r = nameToIndex(sortedfield);
789
790 return (lowerBound(v, r));
791}
792
793template< typename T >
794QPair< T, int > DARowTable< T >::lowerBound(const T& v, int r) const
795{
796 typename DARowTable< T >::SeriesPtr prow = row(r);
797 SeriesIterator ite = std::lower_bound(prow->begin(), prow->end(), v);
798
799 if (ite == prow->end()) {
800 return (qMakePair< T, int >(prow->back(), prow->size() - 1));
801 }
802 size_t dis = std::distance(prow->begin(), ite);
803
804 return (qMakePair< T, int >(*ite, dis));
805}
806
807template< typename T >
808QPair< T, int > DARowTable< T >::upperBound(const T& v, const QString& sortedfield) const
809{
810 const int r = nameToIndex(sortedfield);
811
812 return (upperBound(v, r));
813}
814
815template< typename T >
816QPair< T, int > DARowTable< T >::upperBound(const T& v, int r) const
817{
818 typename DARowTable< T >::SeriesPtr prow = row(r);
819 SeriesIterator ite = std::upper_bound(prow->begin(), prow->end(), v);
820
821 if (ite == prow->end()) {
822 return (qMakePair< T, int >(prow->back(), prow->size() - 1));
823 }
824 size_t dis = std::distance(prow->begin(), ite);
825
826 return (qMakePair< T, int >(*ite, dis));
827}
828
829template< typename T >
831{
832 m_caseSensitivity = cs;
833}
834
835template< typename T >
837{
838 return (m_caseSensitivity == CaseSensitive);
839}
840
841template< typename T >
842void DARowTable< T >::remove(const QString& name)
843{
844 int r = nameToIndex(name);
845 if (r < 0) {
846 return;
847 }
848 remove(r);
849}
850
851template< typename T >
852void DARowTable< T >::remove(int rindex)
853{
854 m_d.remove(rindex);
855 if (0 == m_d.size()) {
856 m_columns = 0;
857 }
858}
859} // end DA
860
861#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
862template< typename T >
863QDebug operator<<(QDebug debug, const DA::DARowTable< T >& t)
864{
865 QDebugStateSaver saver(debug);
866 int rs = t.rowCount();
867 QStringList rns = t.rowNames();
868 int maxlen = 0;
869
870 for (const QString& r : rns) {
871 maxlen = qMax(maxlen, r.size());
872 }
873
874 for (int i = 0; i < rs; ++i) {
875 typename DA::DARowTable< T >::SeriesPtr r = t.row(i);
876 QString name = r->getName();
877 if (name.size() < maxlen) {
878 name.resize(maxlen);
879 }
880 debug.noquote() << name << ":";
881 int cs = r->size();
882 if (cs > 10) {
883 for (int j = 0; j < 5; ++j) {
884 debug.noquote() << r->at(j) << ",";
885 }
886 debug.noquote() << " ...... ";
887 for (int j = cs - 6; j < cs; ++j) {
888 debug.noquote() << r->at(j) << ",";
889 }
890 } else {
891 for (int j = 0; j < cs; ++j) {
892 debug << r->at(j) << ",";
893 }
894 }
895 debug << "\n";
896 }
897
898 return (debug);
899}
900#else
901template< typename T >
902QDebug operator<<(QDebug debug, const DA::DARowTable< T >& t)
903{
904 QDebugStateSaver saver(debug);
905 int rs = t.rowCount();
906 QStringList rns = t.rowNames();
907 int maxlen = 0;
908
909 for (const QString& r : rns) {
910 maxlen = qMax(maxlen, r.size());
911 }
912
913 for (int i = 0; i < rs; ++i) {
914 typename DA::DARowTable< T >::SeriesPtr r = t.row(i);
915 QString name = r->getName();
916 if (name.size() < maxlen) {
917 name.resize(maxlen);
918 }
919 debug.nospace() << name << ":";
920 int cs = r->size();
921 if (cs > 10) {
922 for (int j = 0; j < 5; ++j) {
923 debug.nospace() << r->at(j) << ",";
924 }
925 debug.nospace() << " ...... ";
926 for (int j = cs - 6; j < cs; ++j) {
927 debug.nospace() << r->at(j) << ",";
928 }
929 } else {
930 for (int j = 0; j < cs; ++j) {
931 debug << r->at(j) << ",";
932 }
933 }
934 debug << "\n";
935 }
936
937 return (debug);
938}
939
940#endif
941
942#endif // DAROWTABLE_H
以行为基础的数据表
Definition DARowTable.hpp:54
void clear()
清空
Definition DARowTable.hpp:720
T cell(int r, int c) const
获取单元格
Definition DARowTable.hpp:460
void orderBy(const QString &sn)
orderBy
Definition DARowTable.hpp:774
QStringList rowNames() const
rowNames
Definition DARowTable.hpp:739
int rowCount() const
表的行数
Definition DARowTable.hpp:696
Mode
Definition DARowTable.hpp:57
@ FixedMode
固定模式,表的列不会随着行的变化而变化(默认)
Definition DARowTable.hpp:58
@ ExpandMode
扩展模式,表的列是浮动的,如果插入一行比原来要宽,会自动扩充表的列数
Definition DARowTable.hpp:59
void setCaseSensitivity(CaseSensitivity cs)
设置名字查询时是否对大小写敏感
Definition DARowTable.hpp:830
SeriesPtr & row(int r)
获取行引用
Definition DARowTable.hpp:595
void resize(int r, int c)
改变table 的大小
Definition DARowTable.hpp:402
void setRowNames(const QStringList &ns)
设置行名,如果是个空的表会生成一个默认行
Definition DARowTable.hpp:750
CaseSensitivity
Definition DARowTable.hpp:62
@ CaseInsensitive
大小写不敏感
Definition DARowTable.hpp:63
@ CaseSensitive
大小写敏感
Definition DARowTable.hpp:64
int columnCount() const
表的列数
Definition DARowTable.hpp:702
QPair< T, int > lowerBound(const T &v, const QString &sortedfield) const
查找第一个大于或等于某个元素的位置
Definition DARowTable.hpp:786
QPair< QList< TablePtr >, QList< T > > groupBy(const QString &field) const
groupby
Definition DARowTable.hpp:768
TablePtr takeByValue(const QString &field, T value) const
提取某个值等于value作为新表
Definition DARowTable.hpp:762
void setMode(Mode m)
设置表格的模式
Definition DARowTable.hpp:708
Mode getMode() const
获取模式
Definition DARowTable.hpp:714
void fixSize()
以最大列数进行列数修正,保证所有行同列
Definition DARowTable.hpp:678
void fill(const T &v)
填充元素
Definition DARowTable.hpp:434
bool haveFieldid(const QString &field) const
判断是否存在field
Definition DARowTable.hpp:420
bool isCaseSensitivity() const
判断是否大小写敏感
Definition DARowTable.hpp:836
系列数据,系列允许设置名字
Definition da_data_table.hpp:19
Definition DARowTable.hpp:306
序列化类都是带异常的,使用中需要处理异常
Definition AppMainWindow.cpp:44
QPair< QList< typename DARowTable< T >::TablePtr >, QList< T > > groupby(const DARowTable< T > &table, const QString &field)
groupby 对某个字段执行group by操作
Definition DARowTable.hpp:280
std::shared_ptr< DAVector< _DAValueWithIndex< T > > > makeIndexSeries(const typename DADataTable< T >::SeriesPtr &p)
把序列转换为带序号的序列
Definition da_data_table.hpp:388