user10368959
user10368959

Reputation: 153

How to assign results from 2 separate variables in a third variable?

Pretty trivial question here. Not able to figure out.
I am trying to get results from primaryWork and secondaryWork and assign those results to variable myWorkList. Please let me know what i'm doing wrong here.

Thanks

  let myWorkList
  let primaryWork = this.list.filter(r => r.worker === null)
  let secondaryWork = this.list.filter(r => r.worker === this.currentWorker.id)
  if (this.list) {
    if (this.superuser && this.currentWorker) myWorkList = primaryWork && secondaryWork
  }
  return myWorkList

Upvotes: 1

Views: 57

Answers (1)

stevendesu
stevendesu

Reputation: 16841

It sounds like both primaryWork and secondaryWork are arrays. You're probably looking for the .concat() method:

  let myWorkList
  let primaryWork = this.list.filter(r => r.worker === null)
  let secondaryWork = this.list.filter(r => r.worker === this.currentWorker.id)
  if (this.list) {
    if (this.superuser && this.currentWorker) myWorkList = primaryWork.concat(secondaryWork)
  }
  return myWorkList

Or, fixing some potential bugs in your code:

  // whoever is using the return value from this function expects an array, so if this.list is undefined (or if this.superuser is false) we should return an empty array instead of undefined
  let myWorkList = []
  // if this.list is undefined, this.list.filter will fail - so we do it inside the conditional block
  if (this.list) {
    let primaryWork = [];
    let secondaryWork = [];

    // if this.superuser or this.currentWorker are false, we don't need to waste CPU cycles computing this.list.filter()
    if (this.superuser)
      // I made the assumption (correct me if I'm wrong) that if r.worker is null, the work belongs to the superuser
      primaryWork = this.list.filter(r => r.worker === null)

    // if this.currentWorker is undefined, this.currentWorker.id will fail -- so we perform this filter inside yet another conditional block
    if (this.currentWorker)
      secondaryWork = this.list.filter(r => r.worker === this.currentWorker.id)

    myWorkList = primaryWork.concat(secondaryWork)
  }
  return myWorkList

Finally, you can string this all into a single filter and only iterate over the list once instead of twice, like so:

  return (
    // Check that this.list is defined before filtering
    this.list ?
      this.list.filter(r =>
        // superuser case
        (this.superuser && r.worker === null)
        || // or
        // non-superuser case
        (this.currentWorker && r.worker === this.currentWorker.id)
      )
    // Return an empty array if this.list was undefined
    : []
  );

Note that in this final version we don't instantiate myWorkList, primaryWork, or secondaryWork. We don't need to allocate empty arrays in memory just to garbage collect them later if we can directly return the final value we want. This final form should run 2-3 times faster:

  • Twice as fast since we iterate the this.list array once instead of twice
  • A little bit faster than that because we avoid unnecessary memory allocations

Preliminary benchmarks peg it at about 2.4 faster on my machine:

var list = [{worker: null}, {worker: null}, {worker: 1}, {worker: 2}, {worker: 2}, {worker: 3}, {worker: 4}, {worker: null}, {worker: 2}]

var d0 = new Date(); for (var i = 0; i < 500000; i++) { var primary = list.filter(r => r.worker === null); var secondary = list.filter(r => r.worker === 2); primary.concat(secondary); } console.log(new Date() - d0);
// 659

var d0 = new Date(); for (var i = 0; i < 500000; i++) { list.filter(r => r.worker === null || r.worker === 2); } console.log(new Date() - d0);
// 272

Upvotes: 2

Related Questions