Как я могу найти различие в 2 наборах данных?

Лучше избежать функций побочного эффекта как modifyCollection выше.

А лучший подход должен сделать функцию, которая возвращает измененный набор (или запрос), позволяя начальному неповрежденному.

var modifiedCollection = ModifyCollection(collection, collectionNeedsModification);

var aggregationResult = from a in
                        (from b in modifiedCollection
                         where b.SatisfysCondition)
                         .Aggregate(aggregationFunction)
                    select a.NeededValue;

, Где ModifyCollection является методом, который возвращает измененный набор (или запрос) в параметре в зависимости от collectionNeedsModification булева параметра.

5
задан 14 August 2009 в 08:07
поделиться

4 ответа

(use '[clojure.contrib str-utils duck-streams pprint]
     '[clojure set])

(defn read-bookmarks [filename]
  (apply hash-map
         (mapcat #(re-split #"\|" % 2)
                 (read-lines filename))))

(defn diff-bookmarks [filename1 filename2]
  (let [f1 (read-bookmarks filename1)
        f2 (read-bookmarks filename2)
        k1 (set (keys f1))
        k2 (set (keys f2))
        missing-in-1 (difference k2 k1)
        missing-in-2 (difference k1 k2)
        present-but-different (filter #(not= (f1 %) (f2 %))
                                      (intersection k1 k2))]
    (cl-format nil "~{Id #~a is missing in set #1~%~}~{Id #~a is missing in set #2~%~}~{~{Id #~a is different~%  -> ~a~%  -> ~a~%~}~}"
               missing-in-1
               missing-in-2
               (map #(list % (f1 %) (f2 %))
                    present-but-different))))

(print (diff-bookmarks "bookmarks.csv" "bookmarks2.csv"))
5
ответ дан 13 December 2019 в 05:39
поделиться

поместить первые данные в словарь (хэш-таблицу) с идентификатором в качестве ключа

прочитать следующие данные построчно, извлечь идентификатор из хеша.

  • если идентификатор отсутствует в хэше, вывод: id отсутствует в наборе 1
  • , если значение в имеет другое, output: id is different
  • сохранить идентификаторы во второй хэш-таблице

, затем пройти через ключи первой hashtable

  • проверяет, есть ли они также во второй хеш-таблице. если не выводится: id отсутствует в set2
1
ответ дан 13 December 2019 в 05:39
поделиться

разделите их с помощью regexp и сделайте набор из них с помощью (apply set (re-seq ...), затем вызовите (difference set1 set2), чтобы найти вещи, которые находятся в наборе 1, а не наборе 2, переверните его чтобы найти эти элементы в наборе 2, которых нет в наборе 1.

посмотрите http://clojure.org/data_structures для получения дополнительной информации о наборах clojure.

3
ответ дан 13 December 2019 в 05:39
поделиться

Вот мой подход к функциональному подходу к проблема:

  • Создайте 2 карты, по одной для каждого файла
  • Найдите недостающие элементы между двумя картами, используя disoc
  • Найдите разные, но общие элементы между двумя картами, используя пересечение и фильтр

Код

(ns diffset
  (:use [clojure.contrib.duck-streams]
        [clojure.set]))

(def file1 "bookmarks.csv")
(def file2 "bookmarks2.csv")

(defn split-record [line]
  "split line into (id, bookmark)"
  (map #(apply str %)
       (split-with #(not (= % \|)) line)))

(defn map-from-file [f]
  "create initial map from file f"
  (with-open [r (reader f)]
    (doall (apply hash-map (apply concat (map split-record
                                              (line-seq r)))))))

(defn missing [x y]
  "return seq of all ids in x that are not in y"
  (keys (apply dissoc x (keys y))))

(defn different [x y]
  "return seq of all ids that match but have different bookmark string"
  (let [match-keys (intersection (set (keys x)) (set (keys y)))]
    (filter #(not (= (get x %)
                     (get y %)))
            match-keys)))

(defn diff [file1 file2]
  "print out differences between two bookmark files"
  (let [[s1 s2] (map map-from-file [file1 file2])]
    (dorun (map #(println (format "Id #%s is missing in set #1" %))
                (missing s2 s1)))
    (dorun (map #(println (format "Id #%s is missing in set #2" %))
                (missing s1 s2)))
    (dorun (map #(println (format "Id #%s is different:" %) "\n"
                          " ->" (get s1 %) "\n"
                          " ->" (get s2 %)) (different s1 s2)))))

Результат

user> (use 'diffset)
nil
user> (diff file1 file2)
Id #1 is missing in set #1
Id #5 is missing in set #2
Id #3 is different: 
  -> |www.msnbc.com|Search| 
  -> |www.msnbc.com|Search|New Comment
nil
3
ответ дан 13 December 2019 в 05:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: