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

Inserting Object Into Array Alphabetically From Nested Key Value

My app makes a http call and returns an array of objects. I need to loop over the objects and insert in to a new array in alphabetical order. Problem is the last item in the newly created array is the only item out of order.

Example code: https://stackblitz.com/edit/typescript-zh16xc?file=package.json,index.ts

Aware i can use the native .sort(), however i am opting to forEach because i am performing more operations on each item, but the example has been trimmed down.

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

Code:

import { findIndex } from 'lodash';

let myList = [];

mockHttp()
  .then((res: Array<any>) => {
    console.log(res)
    res.forEach(item => {
      let index = findIndex(myList, function(listItem) { 
        return listItem.name.toLowerCase() > item.name.toLowerCase(); 
      });

      myList.splice(index, 0, {
        name: item.name,
        id: item.id,
        enabled: false
      })
    })

    console.log('result', myList);
  });

function mockHttp() {
   let p = new Promise(function(resolve,reject){
      resolve([
        {
          id: 'dscjidovvocsi', name: 'Pear'
        },
        {
          id: 'dscjidovvocsi', name: 'Banana'
        },
        {
          id: 'dscjidovvocsi', name: 'Orange'
        },
        {
          id: 'dscjidovvocsi', name: 'Blueberry'
        },
        {
          id: 'dscjidovvocsi', name: 'Grapefruit'
        },
        {
          id: 'dscjidovvocsi', name: 'Peach'
        },
        {
          id: 'dscjidovvocsi', name: 'Strawberry'
        },
        {
          id: 'dscjidovvocsi', name: 'Dragonfruit'
        },
        {
          id: 'dscjidovvocsi', name: 'Mango'
        },
        {
          id: 'dscjidovvocsi', name: 'Apples'
        }            
      ]);
   });

   return p;
 }

The last item is:
{
enabled: false,
id: "dscjidovvocsi",
name: "Pear"
}

Which is incorrect, all other items are ordered as expected.

>Solution :

findIndex will return -1 if can’t find a match.

When -1 is passed as an index to splice, it inserts that in the second to last place, since negative indices count from the end, rather than the start.

const arr = [1,2,3]
arr.splice(-1, 0, 4)
console.log(arr) // [1,2,4,3]

So you can fix it by detecting that case and making sure to insert it at the end instead with:

if (index === -1) index = myList.length

For example:

mockHttp()
      .then((res: Array<any>) => {
        console.log(res)
        res.forEach(item => {
          let index = findIndex(myList, function(listItem) { 
            return listItem.name.toLowerCase() > item.name.toLowerCase(); 
          });
          if (index === -1) index = myList.length // added

          myList.splice(index, 0, {
            name: item.name,
            id: item.id,
            enabled: false
          })
        })

        console.log('result', myList);
      });

FYI: I debugged this with this snippet in the loop:

console.log('inserting', item.name, 'at index', index, 'into', myList.map(v => v.name))

Which made it pretty clear what was going on when it logged this:

debug results

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