如何从多维数组中过滤产品?

时间:2019-06-20 07:42:44

标签: javascript arrays json

我有myObject数组和myFilter数组。我想过滤["Front Camera": "16 MP and Above"]的所有产品ID显示的["Front Camera", "16 MP and Above"]产品,然后过滤["Ram", "4 GB"] ["Front Camera", "16 MP and Above"]的所有产品ID显示的["Ram", "4GB"]

再次为["Front Camera", "8 - 11.9 MP"]应用过滤器,并显示具有["Front Camera", "16 MP and Above"]的{​​{1}}和["Front Camera", "8 - 11.9 MP"]的产品ID

["Ram", "4GB"]再次应用过滤器,并且将显示具有["Network Type", "4G"]["Front Camera": "16 MP and Above"]的{​​{1}}和["Front Camera", "8 - 11.9 MP"]的产品ID

您知道所有过滤器通常都具有电子商务网站。我只想针对此复选框click进行过滤

["Ram": "4GB"]

我的过滤器数组是

["Network Type", "4G"]

3 个答案:

答案 0 :(得分:1)

您的过滤器没有返回任何值(通过机器处理)-如果您具有复选框,则JS并不知道6GB比4GB好,因此,如果我还要添加6 GB来进行过滤,请得到A9作为结果(以防您很满意,请接受答案-投票按钮下方):

function run() {
    var simpleFilter = processFilters(myFilter);
    var result = getProducts(simpleFilter, myObject);
    console.log(JSON.stringify(result));
}
function getProducts(filter, products) {
    var retVal = []; // products matching filter criteria
    for(var item in products) {
        var itemCheck = products[item]; // get item data by its #
        var selected = true; // hope we will keep it here
        var itemsChecked = 0; // # of filter items processed
        for(var at in itemCheck.AttriValue) { // iterate attributes
            if(filter[at]) { // at = name of attribute, is at group in filter ?
                itemsChecked++;
                if(filter[at][itemCheck.AttriValue[at]] === undefined) {
                    /* // group at found, but value itemCheck.AttriValue[at] not
                    console.log("Removing " + JSON.stringify(itemCheck));
                    console.log(at + " does not include " + itemCheck.AttriValue[at]);
                    //*/
                    selected = false; // skip product by flag change
                }
            }
        }
        if(selected && itemsChecked == filter.size) retVal.push(itemCheck); // IF we passed ALL unique filter groups without clearing selection, so keep that product
    }
    return retVal;
}
function processFilters(filter) { // double associated search array
    var retVal = [], uniqueItems = 0;
    for(var i=0;i<filter.length;i++) { // 1st level of filter array
        if(retVal[filter[i][0]]) retVal[filter[i][0]][filter[i][1]] = true;
        else { // append next item or below create empty associative array and set its 1st key to true
            var at = {}
            at[filter[i][1]] = true;
            retVal[filter[i][0]] = at;
            uniqueItems++;
        }
    }
    retVal.size = uniqueItems; // save filter groups #
    console.log("Filter size: ", uniqueItems);
    return retVal; // return processed filter
}
var myObject = [
    {
        "ProId": 12,
        "ProName": "Samsung Galaxy A9",
        "AttriValue": {
            "ProductId": "12",
            "Front Camera": "16 MP and Above",
            "Internal Memory": "128 GB and Above",
            "Network Type": "4G",
            "Primary Camera": "16 MP and Above",
            "Ram": "6 GB"
        }
    },
    {
        "ProId": 11,
        "ProName": "Vivo Y95",
        "AttriValue": {
            "ProductId": "11",
            "Front Camera": "16 MP and Above",
            "Internal Memory": "64 GB",
            "Network Type": "4G",
            "Primary Camera": "13 - 15.9 MP",
            "Ram": "4 GB"
        }
    },
    {
        "ProId": 10,
        "ProName": "OPPO A7",
        "AttriValue": {
            "ProductId": "10",
            "Front Camera": "16 MP and Above",
            "Internal Memory": "64 GB",
            "Network Type": "4G",
            "Primary Camera": "13 - 15.9 MP",
            "Ram": "4 GB"
        }
    },
    {
        "ProId": 16,
        "ProName": "Samsung Feature Phone",
        "AttriValue": {
            "Sim Type": "Single",
        }
    }
]
var myFilter = [
    ["Front Camera", "16 MP and Above"],
    ["Front Camera", "8 - 11.9 MP"],
    ["Internal Memory", "128 GB and Above"],
    ["Primary Camera", "16 MP and Above"],
    ["Primary Camera", "8 - 12.9 MP"],
    ["Network Type", "4G"],
    ["Primary Camera", "16 MP and Above"],
    ["Ram", "4 GB"],
    ["Ram", "6 GB"],
    ["Sim Type", "Single"]
]
run();

如果您的过滤器看起来像这样,则无需通过processFilters对其进行转换,并且您可以直接选择是否匹配特定项目:

var myFilter = {
    "Front Camera": {
        "16 MP and Above":true,
        "8 - 11.9 MP":true
    },
    "Internal Memory": {
        "128 GB and Above":true
    },
    "Primary Camera": {
        "16 MP and Above":true,
        "8 - 12.9 MP":true
    },
    "Network Type": {
        "4G": true
    },
    "Primary Camera": {
        "16 MP and Above":true
    },
    "Ram": {
        "4 GB": true,
        "6 GB": true
    }
};

答案 1 :(得分:0)

您可以在下面查看解决方案。

var myObject = [{
    "ProId": 12,
    "ProName": "Samsung Galaxy A9",
    "AttriValue": {
      "ProductId": "12",
      "Front Camera": "16 MP and Above",
      "Internal Memory": "128 GB and Above",
      "Network Type": "4G",
      "Primary Camera": "16 MP and Above",
      "Ram": "6 GB"
    }
  },
  {
    "ProId": 11,
    "ProName": "Vivo Y95",
    "AttriValue": {
      "ProductId": "11",
      "Front Camera": "8 - 11.9 MP",
      "Internal Memory": "64 GB",
      "Network Type": "4G",
      "Primary Camera": "13 - 15.9 MP",
      "Ram": "4 GB"
    }
  },
  {
    "ProId": 10,
    "ProName": "OPPO A7",
    "AttriValue": {
      "ProductId": "10",
      "Front Camera": "16 MP and Above",
      "Internal Memory": "64 GB",
      "Network Type": "4G",
      "Primary Camera": "13 - 15.9 MP",
      "Ram": "4 GB"
    }
  }
];

var myFilter = [
  ["Front Camera", "16 MP and Above"],
  ["Front Camera", "8 - 11.9 MP"],
  ["Internal Memory", "128 GB and Above"],
  ["Primary Camera", "16 MP and Above"],
  ["Primary Camera", "8 - 12.9 MP"],
  ["Network Type", "4G"],
  ["Primary Camera", "48 MP and Above"],
  ["Ram", "6 GB"]
];
let newFilter = {};
myFilter.forEach(function(obj){
  if(newFilter[obj[0]] == undefined){
    newFilter[obj[0]] = [obj[1]];
  }else{
    let oldValue = newFilter[obj[0]];
    newFilter[obj[0]] = oldValue.concat([obj[1]])
  }
});

var result = myObject.filter((obj) => {
  let response = true;
  Object.keys(newFilter).forEach(function(key){
    response = response && newFilter[key].indexOf(obj.AttriValue[key]) >= 0
  });
  return response;
});
console.log(result);
  

答案 2 :(得分:0)

由于结果不清楚,您可以使用评分系统来计算匹配的键/值对的数量,并以此计数来对数组降序进行排序。

此方法使用Map来收集相同的键,而使用Set来收集每个值。将此映射转换为数组,以便以后轻松迭代key和Set

密码检查AttriValue是否存在,以及值是否在Set中。

var data = [{ ProId: 12, ProName: "Samsung Galaxy A9", AttriValue: { ProductId: "12", "Front Camera": "16 MP and Above", "Internal Memory": "128 GB and Above", "Network Type": "4G", "Primary Camera": "16 MP and Above", Ram: "6 GB" } }, { ProId: 11, ProName: "Vivo Y95", AttriValue: { ProductId: "11", "Front Camera": "16 MP and Above", "Internal Memory": "64 GB", "Network Type": "4G", "Primary Camera": "13 - 15.9 MP", Ram: "4 GB" } }, { ProId: 10, ProName: "OPPO A7", AttriValue: { ProductId: "10", "Front Camera": "16 MP and Above", "Internal Memory": "64 GB", "Network Type": "4G", "Primary Camera": "13 - 15.9 MP", Ram: "4 GB" } }, { ProId: 16, ProName: "Samsung Feature Phone", AttriValue: { "Sim Type": "Single" } }],
    filter = [["Front Camera", "16 MP and Above"], ["Front Camera", "8 - 11.9 MP"], ["Internal Memory", "128 GB and Above"], ["Primary Camera", "16 MP and Above"], ["Primary Camera", "8 - 12.9 MP"], ["Network Type", "4G"], ["Primary Camera", "16 MP and Above"], ["Ram", "4 GB"], ["Sim Type", "Single"]],
    map = Array.from(filter.reduce((m, [k, v]) => m.set(k, (m.get(k) || new Set).add(v)), new Map)),
    result = data
        .map(o => [
            map.reduce((c, [k, s]) => c + (k in o.AttriValue && s.has(o.AttriValue[k])), 0),
            o
        ])
        .sort(([a], [b]) => b - a);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

将过滤器值用作集合数组可与Array#every一起使用,并且仅返回具有 all 个属性并具有所需值的项目-在这种情况下,您将获得一个空数组。

var data = [{ ProId: 12, ProName: "Samsung Galaxy A9", AttriValue: { ProductId: "12", "Front Camera": "16 MP and Above", "Internal Memory": "128 GB and Above", "Network Type": "4G", "Primary Camera": "16 MP and Above", Ram: "6 GB" } }, { ProId: 11, ProName: "Vivo Y95", AttriValue: { ProductId: "11", "Front Camera": "16 MP and Above", "Internal Memory": "64 GB", "Network Type": "4G", "Primary Camera": "13 - 15.9 MP", Ram: "4 GB" } }, { ProId: 10, ProName: "OPPO A7", AttriValue: { ProductId: "10", "Front Camera": "16 MP and Above", "Internal Memory": "64 GB", "Network Type": "4G", "Primary Camera": "13 - 15.9 MP", Ram: "4 GB" } }, { ProId: 16, ProName: "Samsung Feature Phone", AttriValue: { "Sim Type": "Single" } }],
    filter = [["Front Camera", "16 MP and Above"], ["Front Camera", "8 - 11.9 MP"], ["Internal Memory", "128 GB and Above"], ["Primary Camera", "16 MP and Above"], ["Primary Camera", "8 - 12.9 MP"], ["Network Type", "4G"], ["Primary Camera", "16 MP and Above"], ["Ram", "4 GB"], ["Sim Type", "Single"]],
    map = Array.from(filter.reduce((m, [k, v]) => m.set(k, (m.get(k) || new Set).add(v)), new Map)),
    result = data.filter(o => map.every(([k, s]) => k in o.AttriValue && s.has(o.AttriValue[k])));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }