2010-10-20 18 views
10

Tôi đang cố hợp nhất hai Bản đồ nhưng không có phương thức tích hợp để tham gia Bộ sưu tập. vậy bạn sẽ làm sao?trong F #, Làm cách nào để hợp nhất 2 trường hợp Collections.Map?

+0

bạn nên xem tại đây (http://stackoverflow.com/questions/590991/merging-two-ienumerablets), về cơ bản map1.Union (map2) nên hoạt động – dvhh

+0

Giảm phân vị: sử dụng toán tử Union của LINQ mà bạn sẽ kết thúc với một IEnumerable của tuple, không hoàn toàn giống như một bản đồ. – Robert

Trả lời

6

Xác định các chức năng sau:

let join (p:Map<'a,'b>) (q:Map<'a,'b>) = 
    Map(Seq.concat [ (Map.toSeq p) ; (Map.toSeq q) ]) 

dụ:

let a = Map([1,11;2,21;3,31;]) 

let b = Map([3,32; 4,41;5,51;6,61;]) 

let c = join a b 

và kết quả:

val c : Map<int,int> = 
    map [(1, 11); (2, 21); (3, 32); (4, 41); (5, 51); (6, 61)] 
+0

Cảm ơn! Những công việc này. – klactose

+1

Hãy nhận biết rằng điều này tái tạo cả hai bản đồ từ đầu mà có thể rất chậm. Một giải pháp tốt hơn là của Robert nếu 'map1' là lớn và' map2' là nhỏ. –

20

Bạn có thể thực hiện điều này bằng Map.fold và Map.add, vì add là thực sự thêm/thay thế:

let map1 = Map.ofList [ 1, "one"; 2, "two"; 3, "three" ] 
let map2 = Map.ofList [ 2, "two"; 3, "oranges"; 4, "four" ] 


let newMap = Map.fold (fun acc key value -> Map.add key value acc) map1 map2 

printfn "%A" newMap 

Có lẽ lý do hợp nhất không được cung cấp ra khỏi hộp là bạn cần để đối phó với xung đột chính. Trong thuật toán kết hợp đơn giản này, chúng ta đơn giản lấy cặp giá trị khóa từ bản đồ thứ hai, đây có thể không phải là hành vi mà bạn muốn.

+0

Thực ra đây chính xác là cách tôi thực hiện điều này: – Massif

9

Một cách khác là thế này:

let merge (a : Map<'a, 'b>) (b : Map<'a, 'b>) (f : 'a -> 'b * 'b -> 'b) = 
    Map.fold (fun s k v -> 
     match Map.tryFind k s with 
     | Some v' -> Map.add k (f k (v, v')) s 
     | None -> Map.add k v s) a b 

Nó cho phép bạn quyết định giá trị bạn muốn nếu có khóa trùng lặp.

Ví dụ:

let a = Map([1,11;2,21;3,31;]) 

let b = Map([3,32; 4,41;5,51;6,61;]) 

merge a b (fun k (v, v') -> v + v');; 

//Result 
val it : Map<int,int> = 
    map [(1, 11); (2, 21); (3, 63); (4, 41); (5, 51); (6, 61)] 

Chú ý rằng chìa khóa 3 là khác nhau.

+0

Lưu ý: bạn không thực sự cần phải chỉ định các loại trên các thông số đầu vào của mình. – Benjol

Các vấn đề liên quan