Search code examples
javascriptarraysobjectnested-loopsfor-of-loop

Nested Loop through the two array for sort by category


let arr = [
     {
          name: 'siggaret',
          type: 'tobbako'
     },
     {
          name: 'fanta',
          type: 'liquid'
     },
     {
          name: 'potato',
          type: 'vegetables'
     },
     {
          name: 'tvorog',
          type: 'milk'
     },
     {
          name: 'steak',
          type: 'meat'
     },
     {
          name: 'kent',
          type: 'tobbako'
     },
     {
          name: 'cola',
          type: 'liquid'
     },
     {
          name: 'potato',
          type: 'vegetables'
     },
     {
          name: 'tvorog',
          type: 'milk'
     },
     {
          name: 'steak',
          type: 'meat'
     },
     {
          name: 'sheep',
          type: 'meat'
     }
]

let categories = [
     {
          type: 'vegetables',
          arr: [],
          count: 0
     },
     {
          type: 'tobbako',
          arr: [],
          count: 0
     },
     {
          type: 'liquid',
          arr: [],
          count: 0
     },
     {
          type: 'other',
          arr: [],
          count: 0
     }
]

/*
    
*/


for (let item of arr) {
     for (let category of categories) {
          if(item.type === category.type){
               category.arr.push(item.name)
               category.count++
          } else {
               category.arr.push(item.name)
               category.count++
          }
     }
}

console.log(categories)

There items is not added in others ? What is the problem ?

I try to sort all items by category.

There nested loop is not worked well but I try with for of and there are some problems with sorted.

When I try to sort by item.name and category.type all items' name is added to the all category.

I have two arrays and I need to find the difference between the two and display them in an unordered list.

I can loop through the master array for a single match but I have no clue how to loop through the master list for more than one key value and do it efficiently.

Below is an excerpt of key values from each array:


Solution

  • Instead of looping through two arrays, you could convert categories into an object, where category type is a key, so you can just use type as key:

    let arr = [
         {
              name: 'siggaret',
              type: 'tobbako'
         },
         {
              name: 'fanta',
              type: 'liquid'
         },
         {
              name: 'potato',
              type: 'vegetables'
         },
         {
              name: 'tvorog',
              type: 'milk'
         },
         {
              name: 'steak',
              type: 'meat'
         },
         {
              name: 'kent',
              type: 'tobbako'
         },
         {
              name: 'cola',
              type: 'liquid'
         },
         {
              name: 'potato',
              type: 'vegetables'
         },
         {
              name: 'tvorog',
              type: 'milk'
         },
         {
              name: 'steak',
              type: 'meat'
         },
         {
              name: 'sheep',
              type: 'meat'
         }
    ]
    
    let categories = {
         'vegetables': {
              arr: [],
              count: 0
         },
         'tobbako': {
              arr: [],
              count: 0
         },
         'liquid': {
              arr: [],
              count: 0
         },
         'other': {
              arr: [],
              count: 0
         }
    }
    
    
    for (let item of arr) {
      //get category object or fallback to "other"
      const category = categories[item.type] || categories.other;
      category.arr.push(item.name)
      category.count++
    }
    
    console.log(categories)
    
    // now we can get an array sorted by count of our categories name
    const sortedByCount = Object.keys(categories) //get array of types
      .sort((a,b) => categories[b].count - categories[a].count) // sort by count
      .map(type => type + " = "  + categories[type].count); // append count
    
    console.log("categories sorted by count", sortedByCount);
    
    //or convert it into array w/sorted names
    const categoriesArray = Object.keys(categories) //get array of types
      .map(type => //convert types into objects
      {
        const category = Object.assign({}, categories[type]); //clone object
      //  const category = categories[type]; //don't clone object
        category.type = type;
    
        category.arr = [...category.arr].sort(); //clone array and sort it
      //  category.arr.sort(); //sort array of names without clonning
        return category;
      })
      .sort((a,b) => b.count - a.count); //sort by count
    console.log("categories as array sorted by count w / sorted names", categoriesArray);
    .as-console-wrapper{top:0;max-height:unset!important;overflow:auto!important;}