我有两个数组,如何找到匹配元素并执行一些操作? (lodash)

时间:2015-10-09 09:49:03

标签: javascript lodash

var array1 = [{Age: 24, Name: "Test", StudentID: 101, Checked: false}, {Age:25, Name: "Test", StudentID: 102, Checked: false}];
var array2 = [{ID: 101}];

如果array1中的任何元素的StudentID属性等于ID中存在的array2属性,我想设置Checked } array1中的属性为true。

任何提示?我想在不编写嵌套的_.each语句的情况下这样做。

这是我的第一次采取;但是,我相信_.some无论如何都会进行互动。

_.each($scope.array1, function(element1) {
          if(_.some($scope.array2, { ID: element1.ID })) {
            element1.Checked = true;
          }
        });

4 个答案:

答案 0 :(得分:2)

你必须使用两个循环,因为你有两个随机长度的数组。但你不必嵌套它们。从ID数组创建一个映射,然后检查索引。

var availableIDs = array2.map(function ( item ) { return item.ID; });
array1.forEach(function ( item ) {
    if (availableIDs.indexOf(item.StudentID) !== -1) item.Checked = true;
});

答案 1 :(得分:1)

使用简单的映射功能,您可以轻松搜索所有对象

var array1 = [{Age: 24, Name: "Test", StudentID: 101, Checked: false}, {Age:25, Name: "Test", StudentID: 102, Checked: false}];
var array2 = [{ID: 101}];
function search(studentList,searchQuery) {
     var results = [];
     studentList.forEach(function(student,sIndex) {
          searchQuery.forEach(function(search,qIndex) {
               if(search.ID == student.StudentID) {
                    results.push(student);
               }
          });       
     })
     return results;
}
search(array1,array2);

forEach函数的作用是迭代每个元素,传递它迭代的索引的对象,以及对象所在的索引。

通过使用双嵌套地图,可以轻松地迭代对象,然后根据您定义的规则进行比较。

然后通过使用范围变量,您可以将匹配值推送到该数组中,为您提供一个漂亮,整洁的结果。

现在请注意,这不是处理此问题的最有效方法。你可以做一个测试,哪个是最长的,并且那个迭代次数最少。 因此,如果学生多于搜索参数,则迭代学生一次。如果搜索参数多于学生,则迭代搜索参与者一次。

你也可以选择预先过滤"数组通过对要排序的索引进行排序,跳过那些你不需要的简单最小/最大排除等等。 但是,最好使用数据库查询来搜索大量数据。 但是如果你只有一个大约1000左右的数据集就足够了。

答案 2 :(得分:1)

使用lodash,使用array1中使用_.indexBy()创建项目地图的序列。使用_.pluck()array2创建一个ID数组,并将其与_.at()一起使用以获取所选项目。使用_.forEach()迭代返回的对象,将Checked属性设置为true,并.commit()应用更改:



function checkById(items, selected) {
  _(items) // start chained sequence
    .indexBy('StudentID') // create a map of student objects by ids
    .at(_.pluck(selected, 'ID')) // create an array of IDs from the objects in the selected array
    .forEach(function(item) { // change the items Checked to true
      item.Checked = true;
    })
    .commit(); // executes the chained sequence
}

var array1 = [{
  Age: 24,
  Name: "Test1",
  StudentID: 101,
  Checked: false
}, {
  Age: 25,
  Name: "Test2",
  StudentID: 102,
  Checked: false
}, {
  Age: 22,
  Name: "Test3",
  StudentID: 103,
  Checked: false
}, {
  Age: 28,
  Name: "Test4",
  StudentID: 104,
  Checked: false
}];

var array2 = [{
  ID: 101
}, {
  ID: 104
}];

checkById(array1, array2);

console.table(array1);

document.getElementById('demo').innerText = JSON.stringify(array1, null, ' ');

<script src="https://cdn.jsdelivr.net/lodash/3.10.1/lodash.min.js"></script>

<pre id="demo"></pre>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

试试这个代码段:

_.each(array1, function (el) {
    el.Checked = !!(JSON.stringify(array2).indexOf(el.StudentID) + 1) || el.Checked;
});

或者,你可以不用lo-dash.js(使用纯JavaScript)

var array1 = [{Age: 24, Name: "Test", StudentID: 101, Checked: false}, {Age:25, Name: "Test", StudentID: 102, Checked: false}];
var array2 = [{ID: 101}];
var students = array1.filter(function(data){
  var isTrue = !!(JSON.stringify(array2).indexOf(data.StudentID)+1);
  data.Checked = isTrue || data.Checked;
  return isTrue;
})
console.log(students)