I have two arrays, how do I find matchings elements and perform some action? (lodash)

懵懂的女人 提交于 2019-12-05 20:32:22

Using lodash, use a sequence in which you create a map of items in array1, using _.indexBy(). Create an array of ids from array2 using _.pluck(), and use them with _.at() to get the selected items. Iterate the returned objects using _.forEach() to set the Checked property to true, and .commit() to apply the changes:

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>

You''ll have to use two loops, since you have two arrays of random length. But you don't have to nest them. Create a map from the array of IDs and then check the index.

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

using a simple mapping function you can compose an easy search through all objects

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);

what the forEach function does is iterate over each element, passing along the object of the index it's iterating, and the index that object is at.

By having a double nested map it's easy to iterate over the objects and then compare them according to the rules you define.

Then by using a scoped variable you can push matching values into that array, giving you a nice, neat clean result to return.

Now please mind, this is not the most efficient way to handle this. You could do a test which arary is longest and have that one iterate the least time. So if there are more students than search parameters iterate the students once. If there are more search parameters than students, iterate the search paramateters once.

also you could chooose to 'prefilter" the arrays by sorting them on the index you wish to sort on, skip the ones you don't need by simple min/max exclusion and such. But you'd be better off using a database query for searching with large quantities of data. But if you only have a dataset of about a 1000 or so this will suffice.

Try this snippet:

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

Or, you can do without lo-dash.js(with pure 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)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!