2016-07-27 15 views
5

Tôi muốn tạo nhóm mới khi chênh lệch giữa các giá trị trong các hàng lớn hơn năm.Làm thế nào tôi có thể nhóm theo sự khác biệt giữa các hàng trong một cột với LINQ và C#?

Ví dụ:

int[] list = {5,10,15,40,45,50,70,75}; 

nên cho tôi 3 nhóm:

1,[ 5,10,15 ] 
2,[40,45,50] 
3,[70,75] 

Có thể sử dụng LINQ ở đây?

Thx!

+0

Có lý do cụ thể mà bạn đang cố gắng sử dụng LINQ ở đây? Những gì bạn đã cố gắng cho đến nay? –

+0

Tôi đã cố gắng giải quyết vấn đề này bằng một vòng lặp (chưa hoàn thành ...). Nhưng trong khi tôi đang viết vòng lặp, nó không giống như một giải pháp tao nhã với tôi:/ – Weissvonnix

Trả lời

4

Khai thác tác dụng phụ (group) không phải là một thói quen tốt, nhưng có thể hữu ích:

int[] list = { 5, 10, 15, 40, 45, 50, 70, 75 }; 

    int step = 5; 
    int group = 1; 

    var result = list 
    .Select((item, index) => new { 
       prior = index == 0 ? item : list[index - 1], 
       item = item, 
      }) 
    .GroupBy(pair => Math.Abs(pair.prior - pair.item) <= step ? group : ++group, 
      pair => pair.item); 

Test:

string report = string.Join(Environment.NewLine, result 
    .Select(chunk => String.Format("{0}: [{1}]", chunk.Key, String.Join(", ", chunk)))); 

Kết quả:

1: [5, 10, 15] 
2: [40, 45, 50] 
3: [70, 75] 
2

bộ sưu tập Giả sử có một indexer được xác định, có thể là một cái gì đó như thế này:

const int step = 5; 
int currentGroup = 1; 
var groups = list.Select((item, index) => 
{ 
    if (index > 0 && item - step > list[index - 1]) 
    { 
     currentGroup++; 
    } 
    return new {Group = currentGroup, Item = item}; 
}).GroupBy(i => i.Group).ToList(); 
2

Theo tôi, chỉ cần viết một chức năng để làm điều đó. Điều này dễ hiểu và dễ đọc hơn các ví dụ về Linq được đưa ra trong các câu trả lời khác.

public static List<List<int>> Group(this IEnumerable<int> sequence, int groupDiff) { 
    var groups = new List<List<int>>(); 
    List<int> currGroup = null; 
    int? lastItem = null; 
    foreach (var item in sequence) { 
     if (lastItem == null || item - lastItem.Value > groupDiff) { 
      currGroup = new List<int>{ item }; 
      groups.Add(currGroup); 
     } else { 
      // add item to current group 
      currGroup.Add(item); 
     } 
     lastItem = item; 
    } 
    return groups; 
} 

Và gọi nó như

List<List<int>> groups = Group(list, 5); 

Assumption này: list được sắp xếp. Nếu nó không được sắp xếp, chỉ cần sắp xếp nó đầu tiên và sử dụng mã trên.

Ngoài ra: nếu bạn cần groupsint[][] chỉ cần sử dụng Phương pháp LINQ ToArray() theo ý thích của bạn.

+0

Tôi nghĩ rằng khả năng đọc phụ thuộc vào lập trình viên. Tôi càng làm việc với các hàm lambda, thì càng dễ đọc cho tôi. – Weissvonnix

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