Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

if/else within reduce function is slowing down result time

I have a reduce function in my Vue app which works perfectly as far as the logic is concerned but it’s incredibly slow.

Luckily, I experimented and found that it’s the if/else at the bottom causing the bottleneck (noticable with thousands of records). If I take out the section noted below, it runs quickly.

Should I plug that portion into a different function and just call it at the end of the reduce, or is there another way (that’s not obvious to me) that will keep things clean and functional?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

<script>
const reduceFunction = (rows) =>
  rows .reduce(
    (a, row) => {
      const employee = a [row .employee] || (a [row .employee] = {dates: {}, total_categories:0, total_items: 0, area: '', group: ''})
      const date = employee .dates [row .itemDate] || (employee .dates [row .itemDate] = {categories: 0, qty: 0, total_categories: 0, unavailable: 0, orders: {}})

      date.categories += +row.categories_per_item * +row.qty
      date.qty += +row.qty

      date.total_categories = date.categories

      const order = date .orders [row .order_number] || (date .orders [row .order_number] = {itemDate: '', skus: {}})

      order.itemDate = row.itemDate;

      const sku = order .skus [row .sku] || (order .skus [row .sku] = {categories: '', qty: '', itemDate: '', expected: '', created: '', unavailable: 0, available:0})

      sku.categories += row.categories_per_item
      sku.qty += row.qty
      sku.itemDate = row.itemDate
      sku.expected = row.shipDate
      sku.created = row.created_date
      sku.heir_id = row.heir_identifier

      employee.total_categories += (+row.categories_per_item * +row.qty)
      employee.total_items += (+row.qty)
      employee.area = row.area
      employee.group = row.group_name
      employee.warehouse = row.warehouse 
      employee.locale = row.locale


      const foundKit = vm.$data.kitsData.find((kit) => kit.heir_identifier === sku.heir_id)

      if (foundKit) {

        new_avail = 10;

        if(sku.qty > new_avail){
          status.status = "Not available";
          date.unavailable += 1
          sku.unavailable += 1
        }else{
          status.status = "Available"
        }
      }else{
        status.status = "No item found"
      }

      return a
    },
    {}
  );


var vm = 
new Vue({
  el: "#app",

  data: {
    rows: [
            {  
                employee: "Adam",
                sku: "A1453",
                categories_per_item: "15",
                area: "1",
                itemDate: "2021-11-02",
                qty: 37,
                group_name: "managers",
                warehouse: "3",
                order_number: "1234",
                locale: "1",
                shipDate: "2020-02-02",
                created_date: "2020-01-01",
                heir_identifier:"ABC3"
            },
            {  
                employee: "Joan",
                sku: "A1453",
                categories_per_item: "15",
                area: "1a",
                itemDate: "2021-11-02",
                qty: 17,
                group_name: "managers",
                warehouse: "3",
                order_number: "34578",
                locale: "1",
                shipDate: "2020-02-02",
                created_date: "2020-01-01",
                heir_identifier:"ABC3"
            },
            {  
                employee: "Bill",
                sku: "A1453",
                categories_per_item: "15",
                area: "1",
                itemDate: "2021-11-03",
                qty: 57,
                group_name: "managers",
                warehouse: "3",
                order_number: "2345",
                locale: "1",
                shipDate: "2020-02-02",
                created_date: "2020-01-01",
                heir_identifier:"ABC3"
            },
            {  
                employee: "PJ",
                sku: "A6512",
                categories_per_item: "150",
                area: "2",
                itemDate: "2021-11-03",
                qty: 20,
                group_name: "managers",
                warehouse: "3",
                order_number: "34567",
                locale: "1",
                shipDate: "2020-02-02",
                created_date: "2020-01-01",
                heir_identifier:"ABC1"
            }
        ]
  },
  methods: {

  },

  computed: {
    employeeData() {
      console.log('employee data')
      employeeRows = reduceFunction(this.rows)
      return employeeRows
      console.log(employeeRows)
    },

    dates() {
      return Array.from(Array(11), (_, i) => new Date(Date.now() + i * 86400000).toISOString().slice(0,10))
    }
    
  }
});


</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
<tr v-for="(value, employee) in employeeData"  :key="employee">
  <td>@{{employee}}</td>
  <td v-for="date in dates" :key="date" >
    <div v-for="(dateInfo, dateValue) in value.dates" :key="dateValue" >
      <div v-if="dateValue == date ">
       
        @{{ dateInfo.total_categories }}
      
      </div>
    </div>
  </td>
</tr>
</div>

>Solution :

It’s almost certainly the find() that’s the bottleneck, not the if.

Create a Set containing all the heir identifiers, then you can quickly check if the current identifier exists.

const reduceFunction = (rows) => {
  let heirs = new Set(vm.$data.kitsData.map(kit => kit.heir_identifier));
  return rows.reduce(
    (a, row) => {
      const employee = a[row.employee] || (a[row.employee] = {
        dates: {},
        total_categories: 0,
        total_items: 0,
        area: '',
        group: ''
      })
      const date = employee.dates[row.itemDate] || (employee.dates[row.itemDate] = {
        categories: 0,
        qty: 0,
        total_categories: 0,
        unavailable: 0,
        orders: {}
      })

      date.categories += +row.categories_per_item * +row.qty
      date.qty += +row.qty

      date.total_categories = date.categories

      const order = date.orders[row.order_number] || (date.orders[row.order_number] = {
        itemDate: '',
        skus: {}
      })

      order.itemDate = row.itemDate;

      const sku = order.skus[row.sku] || (order.skus[row.sku] = {
        categories: '',
        qty: '',
        itemDate: '',
        expected: '',
        created: '',
        unavailable: 0,
        available: 0
      })

      sku.categories += row.categories_per_item
      sku.qty += row.qty
      sku.itemDate = row.itemDate
      sku.expected = row.shipDate
      sku.created = row.created_date
      sku.heir_id = row.heir_identifier

      employee.total_categories += (+row.categories_per_item * +row.qty)
      employee.total_items += (+row.qty)
      employee.area = row.area
      employee.group = row.group_name
      employee.warehouse = row.warehouse
      employee.locale = row.locale

      if (heirs.has(sku.heir_id) {

          new_avail = 10;

          if (sku.qty > new_avail) {
            status.status = "Not available";
            date.unavailable += 1
            sku.unavailable += 1
          } else {
            status.status = "Available"
          }
        } else {
          status.status = "No item found"
        }

        return a
      }, {}
    )
  }
};


var vm =
  new Vue({
    el: "#app",

    data: {
      rows: [{
          employee: "Adam",
          sku: "A1453",
          categories_per_item: "15",
          area: "1",
          itemDate: "2021-11-02",
          qty: 37,
          group_name: "managers",
          warehouse: "3",
          order_number: "1234",
          locale: "1",
          shipDate: "2020-02-02",
          created_date: "2020-01-01",
          heir_identifier: "ABC3"
        },
        {
          employee: "Joan",
          sku: "A1453",
          categories_per_item: "15",
          area: "1a",
          itemDate: "2021-11-02",
          qty: 17,
          group_name: "managers",
          warehouse: "3",
          order_number: "34578",
          locale: "1",
          shipDate: "2020-02-02",
          created_date: "2020-01-01",
          heir_identifier: "ABC3"
        },
        {
          employee: "Bill",
          sku: "A1453",
          categories_per_item: "15",
          area: "1",
          itemDate: "2021-11-03",
          qty: 57,
          group_name: "managers",
          warehouse: "3",
          order_number: "2345",
          locale: "1",
          shipDate: "2020-02-02",
          created_date: "2020-01-01",
          heir_identifier: "ABC3"
        },
        {
          employee: "PJ",
          sku: "A6512",
          categories_per_item: "150",
          area: "2",
          itemDate: "2021-11-03",
          qty: 20,
          group_name: "managers",
          warehouse: "3",
          order_number: "34567",
          locale: "1",
          shipDate: "2020-02-02",
          created_date: "2020-01-01",
          heir_identifier: "ABC1"
        }
      ]
    },
    methods: {

    },

    computed: {
      employeeData() {
        console.log('employee data')
        employeeRows = reduceFunction(this.rows)
        return employeeRows
        console.log(employeeRows)
      },

      dates() {
        return Array.from(Array(11), (_, i) => new Date(Date.now() + i * 86400000).toISOString().slice(0, 10))
      }

    }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <tr v-for="(value, employee) in employeeData" :key="employee">
    <td>@{{employee}}</td>
    <td v-for="date in dates" :key="date">
      <div v-for="(dateInfo, dateValue) in value.dates" :key="dateValue">
        <div v-if="dateValue == date ">

          @{{ dateInfo.total_categories }}

        </div>
      </div>
    </td>
  </tr>
</div>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading