部分匹配和合并行

部分匹配和合并行

我想根据第一个字段部分匹配行,并从匹配的字段中合并第二个字段。

输入示例

Hello:World
Hell0:World2
Helllo:World1
Hel:world4

如果我根据前 4 个字符进行匹配,那么预期的输出将是

Hello:World,World2,World1
Hell0:World2,World,World1
Helllo:World1,World,World2

但我也想知道是否可以匹配基于百分比而不是一定数量的字符?因此,匹配基于90%字符串而不是第一个4字符。

答案1

TXR Lisp 中的解决方案:

$ txr soln.tl < data   # 70% hard-coded in program
Hello:World,World2,World1
Hell0:World2,World,World1
Helllo:World1,World,World2
Hel:world4

代码:

(defvarl %pct% 70)

(defstruct item ()
  key         ;; original key
  eff-key     ;; %pct% percentage of original key
  value       ;; original value
  value-vec  ;; list headed by original, plus others from other items.

  (:postinit (me)
    ;; Initialize eff-key by taking percentage of key.
    (let* ((len (len me.key))
           (pct-len (trunc (+ (* len %pct%) 50) 100)))
      (set me.eff-key (take pct-len me.key)))
    ;; Initialize value list with original value.
    (set me.value-vec (vec me.value))))

(let* ((items (keep-matches (`@key:@value` (get-lines))
                (new item key key value value)))
       (hash [group-by .eff-key items]))
  ;; iterate over all groups of items that have same eff-key
  (dohash (eff-key group-items hash)
    ;; In each group, iterate over all pairs of items (product).
    (each-prod ((i group-items)
                (j group-items))
      ;; For each pair that isn't an item with itself, augment
      ;; the list, by pushing the other item's value onto value-vec.
      (unless (eq i j)
        (vec-push i.value-vec j.value))))
  ;; Produce output
  (each ((i items))
    (put-line `@{i.key}:@{i.value-vec ","}`)))

Hel项目未被删除;目前尚不清楚其标准是什么。

例如,我们可以剔除属于大小为 1 的组的那些项目(没有其他项目共享相同的有效密钥)。

由于这些项目的value-vec长度为 1,因此剔除它们的方法是打印向量中具有两个或多个条目的那些项目:

 ;; Produce output
  (each ((i items))
    (if (>= (len i.value-vec) 2)
      (put-line `@{i.key}:@{i.value-vec ","}`)))

相关内容