尝试从2个数组中筛选出匹配记录,因为1个数组具有不同的结构

时间:2017-03-28 15:13:17

标签: javascript

以下是我的样本记录:

var array1 = [
    {
      "testId": 15,
      "child": [
        {
          "variantId": 100,
          "name": "A1",
        },
        {
          "variantId": 200,
          "name": "A2",
        },
        {
          "variantId": 300,
          "name": "A3",
        },
        {
          "variantId": 400,
          "name": "A4",
        },
        {
          "variantId": 500,
          "name": "A5",
        }
      ]
    }
]


var array2=
[
    {
      "variantId": 100,
      "tests": [
        {
          "testId": 15,
          "flag" : true
        }
      ]
    },
    {
      "variantId": 200,
      "tests": [
        {
          "testId": 15,
          "flag" : false
        }
      ]
    },
    {
      "variantId": 400,
      "tests": [
        {
          "testId": 15,
          "flag" : true
        }
      ]
    },
    {
      "variantId": 500,
      "tests": [
        {
          "testId": 15,
          "flag" : true
        }
      ]
    }
  ]

首先,我将从Array1中获取所选的testId记录。现在我想只从array2中选择那些标志为true的variantId。例如,来自输入VariantIds will be 100,400 and 500

现在使用来自array2的这个选定的variantsIds我想要只获取匹配的variantIds,所以从Array2我想在Array1中搜索100,400 and 500并只从Array1中选择匹配的记录。

预期输出:

"child": [
        {
          "variantId": 100,
          "name": "A1",
        },
        {
          "variantId": 400,
          "name": "A4",
        },
        {
          "variantId": 500,
          "name": "A5",
        }
      ]

到目前为止,我成功地从array1获取了特定的TestId记录,但现在我没有得到如何从array1过滤掉variantId,因为array2的结构有点复杂。



var array1 = [
    {
      "testId": 15,
      "child": [
        {
          "variantId": 100,
          "name": "A1",
        },
        {
          "variantId": 200,
          "name": "A2",
        },
        {
          "variantId": 300,
          "name": "A3",
        },
        {
          "variantId": 400,
          "name": "A4",
        },
        {
          "variantId": 500,
          "name": "A5",
        }
      ]
    }
]

var array2=
[
    {
      "variantId": 100,
      "tests": [
        {
          "testId": 14,
          "flag" : true
        },
        {
          "testId": 15,
          "flag" : true
        }
      ]
    },
    {
      "variantId": 200,
      "tests": [
        {
          "testId": 14,
          "flag" : true
        },
        {
          "testId": 15,
          "flag" : false
        }
      ]
    },
    {
      "variantId": 400,
      "tests": [
        {
          "testId": 14,
          "flag" : true
        },
        {
          "testId": 15,
          "flag" : true
        }
      ]
    },
    {
      "variantId": 500,
      "tests": [
        {
          "testId": 14,
          "flag" : true
        },
        {
          "testId": 15,
          "flag" : true
        }
      ]
    }
  ]
  
  
var testId = 15;

var testObj ={};
 for (var i = 0; i < array1.length; i++) {
            if (array1[i].testId == testId) {
                testObj = array1[i];
                break;
            }
        }
        console.log(testObj);
&#13;
&#13;
&#13;

5 个答案:

答案 0 :(得分:2)

您可以创建一个对象并将其用作哈希表来从array1中的对象过滤child数组

var array1 = [{"testId":15,"child":[{"variantId":100,"name":"A1"},{"variantId":200,"name":"A2"},{"variantId":300,"name":"A3"},{"variantId":400,"name":"A4"},{"variantId":500,"name":"A5"}]}, {"testId":14,"child":[{"variantId":100,"name":"A1"},{"variantId":200,"name":"A2"},{"variantId":300,"name":"A3"},{"variantId":400,"name":"A4"},{"variantId":500,"name":"A5"}]}]
var array2=[{"variantId":100,"tests":[{"testId":14,"flag":true},{"testId":15,"flag":true}]},{"variantId":200,"tests":[{"testId":14,"flag":true},{"testId":15,"flag":false}]},{"variantId":400,"tests":[{"testId":14,"flag":false},{"testId":15,"flag":true}]},{"variantId":500,"tests":[{"testId":14,"flag":true},{"testId":15,"flag":true}]}]

var obj = {}
array2.forEach(function(e) {
  e.tests.forEach(function(test) {
    if (test.flag) obj[e.variantId + '|' + test.testId] = true;
  })
})

var result = array1.reduce(function(r, e) {
  var o = {testId: e.testId,child: []}

  var child = e.child.filter(function(a) {
    return obj[a.variantId + '|' + e.testId]
  })
  
  o.child = child;
  r.push(o)
  return r;
}, [])

console.log(JSON.stringify(result, 0, 4))

答案 1 :(得分:2)

您可以使用哈希表并首先获取所有true标志,过滤子数组。

function getChildren(data, flags, testId) {
    var hash = Object.create(null),
        result;

    flags.forEach(function (a) {
        a.tests.forEach(function (b) {
            b.testId === testId && b.flag && (hash[a.variantId] = true);
        });
    });

    data.forEach(function (a) {
        if (a.testId === testId) {
            result = {
                child: a.child.filter(function (b) {
                    return hash[b.variantId];
                })
            };
        }
    });
    return result;
}

var array1 = [{ testId: 15, child: [{ variantId: 100, name: "A1", }, { variantId: 200, name: "A2", }, { variantId: 300, name: "A3", }, { variantId: 400, name: "A4", }, { variantId: 500, name: "A5", }] }],
    array2 = [{ variantId: 100, tests: [{ testId: 15, flag: true }] }, { variantId: 200, tests: [{ testId: 15, flag: false }] }, { variantId: 400, tests: [{ testId: 15, flag: true }] }, { variantId: 500, tests: [{ testId: 15, flag: true }] }],
    array3 = [{ testId: 15, child: [{ variantId: 100, name: "A1", }, { variantId: 200, name: "A2", }, { variantId: 300, name: "A3", }, { variantId: 400, name: "A4", }, { variantId: 500, name: "A5", }] }],
    array4 = [{ variantId: 100, tests: [{ testId: 14, flag: true }, { testId: 15, flag: true }] }, { variantId: 200, tests: [{ testId: 14, flag: true }, { testId: 15, flag: false }] }, { variantId: 400, tests: [{ testId: 14, flag: true }, { testId: 15, flag: true }] }, { variantId: 500, tests: [{ testId: 14, flag: true }, { testId: 15, flag: true }] }],
    testId = 15;

console.log(getChildren(array1, array2, testId));
console.log(getChildren(array3, array4, testId));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:1)

根据Nenad的回答,为了让这个与array1中的多个元素一起使用,您可以在.reduce()上使用array1并将结果连接成最终数组,如下所示:

这也考虑了变量中的多个测试,并将每个testId及其相应的标志值映射到一个对象中,以迭代以创建最终结果。

var array1 = [{"testId":15,"child":[{"variantId":100,"name":"A1"},{"variantId":200,"name":"A2"},{"variantId":300,"name":"A3"},{"variantId":400,"name":"A4"},{"variantId":500,"name":"A5"}]}]
var array2 = [{"variantId":100,"tests":[{"testId":15,"flag":true}]},{"variantId":200,"tests":[{"testId":15,"flag":false}]},{"variantId":400,"tests":[{"testId":15,"flag":true}]},{"variantId":500,"tests":[{"testId":15,"flag":true}]}]
var testId = 15;
var obj = array2.reduce(function(result, current) {
    // create object accessable by variantId and testIds
    result[current.variantId] = current.tests.reduce(function (res, curr) {
        if (curr.testId === testId) {
          res[curr.testId] = curr.flag;
        }
        return res;
    }, {});
    // result has the following structure: 
    // { "100": { "14": true, "15": true, ... }, ...} where 100 is the variantId
    //  14/15 are testIds and the boolean is the flag value of the testId
    return result;
}, {});

var result = array1.reduce(function (res, current) {
    return res.concat(current.child.filter(function(elem) {
      // ensure that both the variantId and the testId match and testId is true
      return obj[elem.variantId] && obj[elem.variantId][current.testId];
    }));
}, []);

console.log(result)

答案 3 :(得分:1)

如果您尝试这样做,并执行..

undefined

答案 4 :(得分:1)

你也可以像我在这段代码中那样做

babel src/** -d lib

工作片段如下:

var trueElements=array2.map(element=>{
     if(element.tests[0].testId == testId && element.tests[0].flag == true){
        return element.variantId;
    };
});


 var child = testObj.child.filter(element=>trueElements.indexOf(element.variantId)>-1));