2015-10-05 3 views
2

Я хочу фильтровать массив продуктов JSON на основе критериев категории. Возможно, решение будет заключаться в настройке JSON по-разному, но я не уверен, как будет выглядеть этот JSON. Вот мой текущий JSON:Фильтр нескольких категорий JSON

var myData = { 
    "products": [ 
     { 
      "name": "Multi Color 1", 
      "price": "2.99", 
      "color": [ 
       { 
        "type": "red" 
       }, 
       { 
        "type": "blue" 
       } 
      ] 
     }, 
     { 
      "name": "Multi Color 2", 
      "price": "2.99", 
      "color": [ 
       { 
        "type": "red" 
       }, 
       { 
        "type": "green" 
       } 
      ] 
     }, 
     { 
      "name": "Single Color", 
      "price": "2.99", 
      "color": [ 
       { 
        "type": "red" 
       } 
      ] 
     } 
    ] 
} 

Так что, если я фильтрация по «красной», он будет возвращать все три продукта. Но если фильтрация «зеленым» или «синим», она будет возвращать только один продукт. Я пробовал $ .grep и $ .map, но я не могу получить несколько уровней для правильного возврата продуктов. Буду признателен за любую оказанную помощь.

Один из моих попыток был:

testMap = $.grep(myData.products, function(element, index) { 
    return $.grep(element.color, function(element, index) { 
     return (element.value === "green"); 

    }); 
}); 
+0

изменение '' color' к «color»: [«red», «green»] 'немного упростит фильтр, но не будет пробной пробкой. Покажите код, который вы пытались сперва, хотя. Показ ваших попыток не похож на то, что вы хотите, чтобы другие делали вашу работу за вас. – charlietfl

+0

Спасибо charlietfl. Я отредактировал, чтобы добавить одну попытку, я просто просматривал другой код в jsfiddle. Я попытаюсь использовать упрощенную цветовую матрицу. – user2680673

+0

ОК ... так что вы были довольно близки .... лучше учиться на том, что пошло не так, как начать с нуля – charlietfl

ответ

0

Придерживание с помощью JQuery $.grep, который в основном обертка для Array.prototype.filter()

function filterByColor(colorSearch, arr){ 
    return $.grep(arr,function(item){ 
     return $.grep(item.color,function(col){ 
      return col.type === colorSearch 
     }).length;    
    });  
} 

console.log(filterByColor('red',myData.products)) 

DEMO

EDIT: Исправьте свой код. Необходимо, чтобы вернуть длину внутреннего массива, который действует как логическое значение, и изменения в element.type

testMap = $.grep(myData.products, function(element, index) { 
    return $.grep(element.color, function(element, index) { 
     // check the `type` 
     return (element.type === "green"); 
    // return the length , zero means no match and is falsy 
    }).length; 
}); 

Finally:

Изменение в структуре color:['red', 'green'] бы simplfy к:

testMap = $.grep(myData.products, function(element, index) { 
     return $.inArray('green', element.color) > -1; 
}); 
+0

Спасибо! Я продолжал играть с ним и имел $ .grep, встроенный в решение $ .map, но ваш гораздо чище. – user2680673

0

На высоком уровне, что вы хотите:

filteredData = grep(myData, function(item) { 
    return any(item.color, function(color) { 
    return color.type === myColor; 
    }); 
}); 

Где any это функция, которая говорит вам, является ли какой-либо из элементов в массиве удовлетворяют определенному предикату. AFAIK jQuery не имеет такой функции из коробки, но ее легко написать.

В переводе на обычный JavaScript, все это включает в себя несколько вложенных циклов:

var filterMyData = function(data, color) { 
    var result = []; 
    var products = data.products; 
    for(var i = 0, n = products.length; i < n; ++i) { 
    var product = products[i]; 
    var colors = product.color; 
    for(var j = 0, m = colors.length; j < m; ++j) { 
     if(colors[j].type === color) { 
     result.push(products); 
     break; 
     } 
    } 
    } 
    return result; 
}; 

console.log(filterMyData(myData, 'red')); 
Смежные вопросы