2014-11-02 24 views
5

Tôi đang cố gắng để có được một kết quả tìm kiếm một cái gì đó như thế này: Miniors | Boys | 54kg - 62kg nơi mà mọi giá trị được giới hạn bởi một đường ống | xuất phát từ một mảng chứa "loại hạn chế" nhất định. Ví dụ: ageGroups, genders, weightClasses (như đã xem ở trên).Dynamic lồng nhau cho các vòng được giải quyết với đệ quy

Cách tôi có thể nhận được kết quả này ngay bây giờ là nếu tôi mã cứng lồng nhau cho các vòng lặp (sử dụng dấu gạch dưới), nhưng điều này có nghĩa là bây giờ tôi phải lặp lại bao nhiêu mảng để có được kết quả mong muốn . Điều này hoạt động "tốt":

var categories = []; 
_.each(ageGroups, function(ageGroup) { 
    _.each(gender, function(gender) { 
    _.each(weightClasses, function(weightClass) { 
     categories.push(ageGroup.name + ' | ' + gender.name + ' | ' + weightClass.name); 
     }); 
    }); 
}); 

Đầu ra là một mảng (danh mục) với tất cả các kết hợp có thể của mảng giới hạn.

Bây giờ, vấn đề của tôi là tôi cần một cách để làm tương tự với một số lượng các mảng hạn chế không xác định. đoán của tôi cho một giải pháp thích hợp là đệ quy, NHƯNG tôi đã không thể sản xuất bất cứ điều gì thực sự hoạt động kể từ khi tôi không thể quấn quanh đầu tôi đệ quy chỉ được nêu ra :)

Một fiddle chuẩn bị với một số dữ liệu thử nghiệm có thể tìm thấy tại đây: jsFiddle. Fiddle sử dụng góc cho một số dữ liệu đơn giản và gỡ lỗi kết quả đầu ra và underscorejs để xử lý các mảng.

+0

Cố gắng không để sử dụng các hiệu ứng phụ (tức là 'push'ing thành mảng' categories' toàn cục), nhưng thay vào đó 'return' từ mỗi bước và sử dụng' map' (và 'flatten') – Bergi

+0

Hmm .. Okey. Flatten sẽ không được sử dụng ở đây vì tôi cần một sự kết hợp của các giá trị khác nhau từ các mảng khác nhau. Nhưng bản đồ có thể là một cái gì đó .. Mặc dù tôi không thể nhìn thấy nó sẽ giải quyết vấn đề tôi đang phải đối mặt với một số lượng năng động của mảng. Bạn quan tâm để xây dựng? – aup

+0

Hãy thử sử dụng 'map' (ngay cả trong một cách không chung chung) và bạn sẽ thấy những gì bạn cần' flatten' cho. Sau đó, tạo một hàm nhận 'nhóm', chỉ mục của nhóm hiện tại (" cấp độ làm tổ ") và tên hiện tại của các nhóm đã truy cập. Trường hợp cơ sở (khi mức độ làm tổ đã đạt đến độ dài của 'nhóm') sau đó sẽ trả về các tên hiện tại đó (tham gia bởi' | '), trường hợp đệ quy - bạn sẽ tìm ra. – Bergi

Trả lời

2

Gần đây tôi đã viết một hàm đệ quy để tạo tất cả các kết hợp của mảng. Bạn sẽ phải dịch dữ liệu của bạn thành một mảng các mảng mà hàm của tôi sử dụng, nhưng điều đó không khó.

Dù sao, đây là đoạn code với một ví dụ Runnable:

var v = [['Miniors','Kadettes','Juniors', 'Seniors'], ['Boys','Girls','Men','Women'],['54kg - 62kg','64kg - 70kg','71kg - 78kg','79kg - 84kg']]; 
 
var combos = createCombinations(v); 
 
for(var i = 0; i < combos.length; i++) { 
 
    document.getElementsByTagName("body")[0].innerHTML += combos[i] + "<br/>"; 
 
} 
 

 
function createCombinations(fields, currentCombinations) { 
 
    //prevent side-effects 
 
    var tempFields = fields.slice(); 
 

 
    //recursively build a list combinations 
 
    var delimiter = ' | '; 
 
    if (!tempFields || tempFields.length == 0) { 
 
    return currentCombinations; 
 
    } 
 
    else { 
 
    var combinations = []; 
 
    var field = tempFields.pop(); 
 

 
    for (var valueIndex = 0; valueIndex < field.length; valueIndex++) { 
 
     var valueName = field[valueIndex]; 
 

 
     if (!currentCombinations || currentCombinations.length == 0) { 
 
     var combinationName = valueName; 
 
     combinations.push(combinationName); 
 
     } 
 
     else { 
 
     for (var combinationIndex = 0; combinationIndex < currentCombinations.length; combinationIndex++) { 
 
      var currentCombination = currentCombinations[combinationIndex]; 
 
      var combinationName = valueName + delimiter + currentCombination; 
 
      combinations.push(combinationName); 
 
     } 
 
     } 
 
    } 
 
    return createCombinations(tempFields, combinations); 
 
    } 
 
}

+0

Công cụ tuyệt vời! Trông rất đẹp, cảm ơn! – aup

2
function iterate(lists, fn) 
{ 
    var values = []; 
    function process(listIndex) 
    { 
    var list = lists[listIndex]; 

    // no list? create the value 
    if (!list) 
    { 
     fn.apply(null, values); 
     return; 
    } 

    for (var i = 0; i < list.length; i++) 
    { 
     values[listIndex] = list[i]; 
     process(listIndex+1); 
    } 
    } 

    process(0); 
} 

đây là một ví dụ làm việc dựa trên các dữ liệu đề cập trong câu hỏi của bạn: http://jsbin.com/boqucu/2/edit

+0

Điều này hoạt động hoàn hảo "out-of-the-box" cho trường hợp cụ thể của tôi! Tại sao mọi người lại bỏ phiếu này? Tôi không bao giờ thấy cách tôi có thể sử dụng động này? Hàm đặt cùng tên cuối cùng lấy một số thông số cụ thể. Cảm ơn! – aup

+0

ít nhất ai cũng cho tôi một số thông tin. Tôi sẽ cập nhật câu trả lời của mình. Cảm ơn. – lloiser

+0

Công cụ tuyệt vời! Chỉ cần thay đổi cuộc gọi fn để chỉ chuyển vào mảng giá trị thay vì fh.apply(). Tôi nghĩ điều đó đã xảy ra! Cảm ơn một lần nữa! – aup

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