77077 发表于 2014-8-6 16:26:00

表数据分组统计的问题~

假如有一建筑物数据组
;(建筑类型 基底面积 建筑面积)
(setq lst '(
("居住" "1431.05" "8586.30")
("居住" "1329.99" "7979.94")
("商业" "596.30" "1788.90")
("公共设施" "395.54" "791.08")
("其他" "365.70" "731.40")
("居住" "1311.85" "7871.10")
("居住" "1965.39" "11792.34")
("公共设施" "507.51" "1015.02")
("公共设施" "668.77" "1337.54")
("公共设施" "502.95" "1005.90")
("公共设施" "574.56" "1149.12")
("其他" "660.27" "1320.54")
))
如何将他们按照建筑类型进行分组,并统计出总基底面积和总建筑面积?
下面每项都要有数值,如果没有此类建筑,总和为0?
(setq lstb '("居住" "宾馆饭店" "商业" "金融" "办公" "娱乐" "厂房" "公共设施" "其他"))

最终统计出来的数据表可能是是((居住总基底面积 总建筑面积) (宾馆饭店总基底面积 总建筑面积) (商业总基底面积 总建筑面积) ....)这种格式.

77077 发表于 2014-8-6 16:47:59

本帖最后由 77077 于 2014-8-7 13:47 编辑

结合高手给的思路,编写完成(defun c:tt()
(setq lst1 '(("居住" "1431.05" "8586.30")
               ("居住" "1329.99" "7979.94")
               ("商业" "596.30" "1788.90")
               ("公共设施" "395.54" "791.08")
               ("其他" "365.70" "731.40")
               ("居住" "1311.85" "7871.10")
               ("居住" "1965.39" "11792.34")
               ("公共设施" "507.51" "1015.02")
               ("公共设施" "668.77" "1337.54")
               ("公共设施" "502.95" "1005.90")
               ("公共设施" "574.56" "1149.12")
               ("其他" "660.27" "1320.54")
            )
      lstb '("居住" "宾馆饭店" "商业" "金融" "办公" "娱乐" "厂房" "公共设施" "其他")
      lst2 '())
;表分组
(setq lst2
   (mapcar '(lambda(x y)
   (cons y (vl-remove nil
         (mapcar '(lambda(x)
                  (if (member y x) (append x lst2))
               )
            lst1
            )
            )
      )
    )
   lst1 lstb
   )
)
;分组求和
(mapcar '(lambda (x)
            (if (setq b (cdr x)
                     c (rtos (apply '+ (mapcar 'atof (mapcar 'cadr b)))2 2)
                     d (rtos (apply '+ (mapcar 'atof (mapcar 'caddr b)))2 2)
                     )
            (list (car x) c d)
            (list (car x) "0" "0")
            )
          )
         lst2
   )
)测试结果:
命令: tt
(("居住" "6038.28" "36229.68")
("宾馆饭店" "0.00" "0.00")
("商业" "596.30" "1788.90")
("金融" "0.00" "0.00")
("办公" "0.00" "0.00")
("娱乐" "0.00" "0.00")
("厂房" "0.00" "0.00")
("公共设施" "2649.33" "5298.66")
("其他" "1025.97" "2051.94"))

xyp1964 发表于 2014-8-6 17:16:21

本帖最后由 xyp1964 于 2014-8-6 17:20 编辑

(("公共设施" 2649.33 5298.66) ("居住" 6038.28 36229.7) ("其他" 1025.97 2051.94) ("商业" 596.3 1788.9))(setq lst'(("居住" "1431.05" "8586.30")             ("居住" "1329.99" "7979.94")
             ("商业" "596.30" "1788.90")
             ("公共设施" "395.54" "791.08")
             ("其他" "365.70" "731.40")
             ("居住" "1311.85" "7871.10")
             ("居住" "1965.39" "11792.34")
             ("公共设施" "507.51" "1015.02")
             ("公共设施" "668.77" "1337.54")
             ("公共设施" "502.95" "1005.90")
             ("公共设施" "574.56" "1149.12")
             ("其他" "660.27" "1320.54")
            )
      lst (xyp-count1(vl-sort lst'(lambda(x y)(<(car x)(car y)))))
      lst (mapcar '(lambda (x)
                      (setq b(cdr x)
                            c(apply '+(mapcar'distof(mapcar'car b)))
                            d(apply '+(mapcar'distof(mapcar'cadr b)))
                      )
                      (list(car x) c d)
                  )
                   lst
         )
)

77077 发表于 2014-8-6 17:18:48

本帖最后由 77077 于 2014-8-6 17:20 编辑

没错,就是要这样的,不过院长的好像少了些东西,例如:
("娱乐" "0" "0")

最好能按 lstb里面的顺序排列,没有的就0表示~

77077 发表于 2014-8-6 17:29:48

院长写的(apply '+ (mapcar 'distof (mapcar 'cadr b)))
我写的(apply '+ (mapcar '(lambda(x) (atof (cadr x))) lst))
晕了晕了~

wowan1314 发表于 2014-8-6 21:05:20

本帖最后由 wowan1314 于 2014-8-6 23:27 编辑

这个是个体力活!

喜欢这样的代码,看着很漂亮!


(("居住" 6038.28 36229.7) ("宾馆饭店" "0" "0") ("商业" 596.3 1788.9) ("金融"
"0" "0") ("办公" "0" "0") ("娱乐" "0" "0") ("厂房" "0" "0") ("公共设施" 2649.33
5298.66) ("其他" 1025.97 2051.94))(defun t11 (l ll)
    (mapcar
      '(lambda(a b)
            (if (= a (car b))
                b
                (cons a
                  (eval
                        (cons 'mapcar
                            (cons ''+
                              (mapcar
                                    '(lambda(x)
                                        (cons 'list x)
                                    )
                                    b
                              )
                            )
                        )
                  )
                )
            )
      )
      ll
      (mapcar
            '(lambda(x)
                (if (assoc x l)
                  (mapcar
                        '(lambda(y)
                            (if (= x (car y))
                              (mapcar 'atof (cdr y))
                              '(0 0)
                            )
                        )
                        l
                  )
                  (list x "0" "0")
                )
            )
            ll
      )
    )
)

77077 发表于 2014-8-6 21:40:40

hoho~~~
我估计也是个体力活,这么多mapcar。
明天测试下看看。

77077 发表于 2014-8-6 21:49:14

可不可以换种思路解题
setq将("居住" "宾馆饭店" "商业" "金融" "办公" "娱乐" "厂房" "公共设施" "其他")中的每一个设置成空数据,如:(setq lst1 '("居住"“0” “0”) lst2 '("宾馆饭店"“0” “0”)...)
然后顺序读取 lst 中的每一项,分别取出(cadr)(caddr)加到对应的表中,最后将表合并起来组成最终的表~

坏处是借用一大堆的lst1...lstn,可能会影响效率~

xyp1964 发表于 2014-8-6 23:22:02

本帖最后由 xyp1964 于 2014-8-6 23:23 编辑

77077 发表于 2014-8-6 21:49 static/image/common/back.gif
可不可以换种思路解题
setq将("居住" "宾馆饭店" "商业" "金融" "办公" "娱乐" "厂房" "公共设施" "其他" ...
结果:
(("居住" 6038.28 36229.7)
("宾馆饭店" 0 0)
("商业" 596.3 1788.9)
("金融" 0 0)
("办公" 0 0)
("娱乐" 0 0)
("厂房" 0 0)
("公共设施" 2649.33 5298.66)
("其他" 1025.97 2051.94)
)(defun c:tt ()
(setq lst1 '(("居住" "1431.05" "8586.30")
               ("居住" "1329.99" "7979.94")
               ("商业" "596.30" "1788.90")
               ("公共设施" "395.54" "791.08")
               ("其他" "365.70" "731.40")
               ("居住" "1311.85" "7871.10")
               ("居住" "1965.39" "11792.34")
               ("公共设施" "507.51" "1015.02")
               ("公共设施" "668.77" "1337.54")
               ("公共设施" "502.95" "1005.90")
               ("公共设施" "574.56" "1149.12")
               ("其他" "660.27" "1320.54")
            )
      lst2 '("居住" "宾馆饭店" "商业" "金融" "办公" "娱乐" "厂房" "公共设施" "其他")
      lst3 (mapcar '(lambda (x) (list x)) lst2)
)
(foreach a lst1
    (setq name (car a)
          nn (- (length lst2) (length (member name lst2)))
          i -1
          lst3 (mapcar '(lambda (x)
                        (setq i (1+ i))
                        (if (= i nn)(cons (cdr a) x)x)
                        )
                     lst3
               )
    )
)
(mapcar '(lambda (x)
             (setq b (cdr x)
                   c (apply '+ (mapcar 'distof (mapcar 'car b)))
                   d (apply '+ (mapcar 'distof (mapcar 'cadr b)))
             )
             (list (car x) c d)
         )
          (mapcar 'reverse lst3)
)
)

wowan1314 发表于 2014-8-6 23:39:30

本帖最后由 wowan1314 于 2014-8-6 23:43 编辑

这个院长的!

还是觉的mapcar 叠一起好看! 哈哈

页: [1] 2
查看完整版本: 表数据分组统计的问题~