0

My requirement is, if I select a single category for the subscription on my client side, then I am sending that category details related to that category, and storing those in my backend with some id's and then pushing back to the client side to show those categories in one section to my user. So I will get an array of like below which is coming from my backend DB

[
  {
   catId:"veg",
   catName:"vegetarian",
   subCatId:"potato", 
   subcatName:"potatoes"
  },
  {
   catId:"veg",
   catName:"vegetarian",
   subCatId:"tomato", 
   subcatName:"tomatoes"
  },
  {
   catId:"nonveg",
   catName:"Non vegetarians",
   subCatId:"chicken", 
   subcatName:"chicken"
  },
  {
   catId:"apetizer",
   catName:"Apitizers",
   subCatId:"veg-apitizer", 
   subcatName:"vegetarian Apitizers"
  }  
]

Now I want the resultant array like as below,

  [
     {
      catId:"veg",
      catName:"vegetarian",
      subcatsArray:[
                     {
                       catId:"veg",
                       catName:"vegetarian",
                       subCatId:"potato",
                       subcatName:"potatoes"
                      }, 
                      {
                       catId:"veg",
                       catName:"vegetarian",
                       subCatId:"tomato", 
                       subcatName:"tomatoes"
                      }
                    ]
     },
     {
      catId:"nonveg",
      catName:"Non vegiterians",
      subcatsArray:[
                     {
                       catId:"nonveg",
                       catName:"Non vegiterians",
                       subCatId:"chicken",
                       subcatName:"chicken"
                      }
                    ]
     },{
      catId:"apetizer",
      catName:"Apitizers",
      subcatsArray:[
                     {
                       catId:"apetizer",
                       catName:"Apitizers",
                       subCatId:"veg-apitizer",
                       subcatName:"vegetarian Apitizers"
                      }
                    ]
     }

    ]

If again, I am subscribing to another sub-category, then I want to push that sub-category into that related category array of subcatsArray as shown in the model structure above.

Note: I am showing the resultant subscribed categories in another page where as I am subscribing categories, subcategories in separate page

2
  • Also post the code that you attempted. Commented Aug 4, 2017 at 8:42
  • Also I don't think you need catId and catName in subcatsArray as it is just repetition of data. Commented Aug 4, 2017 at 8:44

4 Answers 4

1

Here is a starter to what i think you are after.

var catarray = [];//your array
var formatedArray = [];    
function sort() {

      for (var i=0; i < catarray.length; i++) {
          addToFormated(Stored_Rights[i].catId,Stored_Rights[i].catName, Stored_Rights[i].subCatId,Stored_Rights[i].subcatName);

      }
    }
    function addToFormated(a,b,c,d) {
       var found = false;
       for (var i=0; i < formatedArray.length; i++) {
          if (formatedArray[i].catId == a) {
              found = true;
             //add the cat food to this area of the array
          }
       }
       if (!found) {
          //create a new catagory and add
       }
    }
Sign up to request clarification or add additional context in comments.

Comments

1

You could use a nested hash table and take only the parts which are not in the result set.

var array = [{ catId: "veg", catName: "vegetarian", subCatId: "potato", subcatName: "potatoes" }, { catId: "veg", catName: "vegetarian", subCatId: "potato", subcatName: "potatoes" }, { catId: "veg", catName: "vegetarian", subCatId: "tomato", subcatName: "tomatoes" }, { catId: "nonveg", catName: "Non vegetarians", subCatId: "chicken", subcatName: "chicken" }, { catId: "apetizer", catName: "Apitizers", subCatId: "veg-apitizer", subcatName: "vegetarian Apitizers" }],
    hash = Object.create(null),
    result = [];

array.forEach(function (o) {
    if (!hash[o.catId]) {
        hash[o.catId] = { _: [] };
        result.push({ catId: o.catId, catName: o.catName, subcatsArray: hash[o.catId]._ });
    }
    if (!hash[o.catId][o.subCatId]) {
        hash[o.catId][o.subCatId] = o;
        hash[o.catId]._.push(o);
    }
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

0
<div id="log"></div>
<script>
var source = [{
        catId: "veg",
        catName: "vegetarian",
        subCatId: "potato",
        subcatName: "potatoes"
    },
    {
        catId: "veg",
        catName: "vegetarian",
        subCatId: "tomato",
        subcatName: "tomatoes"
    },
    {
        catId: "nonveg",
        catName: "Non vegetarians",
        subCatId: "chicken",
        subcatName: "chicken"
    },
    {
        catId: "apetizer",
        catName: "Apitizers",
        subCatId: "veg-apitizer",
        subcatName: "vegetarian Apitizers"
    }
];

var treestructure = []; // keep this in global scope

window.onload = function() {
    flat2tree(source);
    document.getElementById('log').innerHTML = JSON.stringify(treestructure);
}

function flat2tree(source) {
    for (var i in source) {
        var cat = source[i]['catId'];
        // see if the cat is already in the treestructure
        var index = inTree(treestructure, 'catId', cat);
        if (index > -1) {
            // add this item to the subarray
            treestructure[index]['subcatsArray'].push(source[i]);
        } else {
            // new category, add to tree
            treestructure.push({
                catId: cat,
                catName: source[i]['catName'],
                subcatsArray: [
                    source[i]
                ]
            });
        }
    }
}

// a kind of inArray, or indexOf, but especially for this kind of tree.  returns -1 for 'not found', else returns the index
function inTree(obj, tag, value) {
    for (var i in obj) {
        if (obj[i][tag] == value) {
            return i;
        }
    }
    return -1;
}
</script>

Comments

0

With es6 you can do something short by using a collection like Map with Reduce to hash on the catid and then spread the values into an array. or you can use closures and follow Ninas pattern.However, Nina's solution is faster and more elegant since her solution only contains one loop and it's the most direct solution to the problem.

const catagoriseDuplicates = list => [...list.reduce((map, list) =>
  (map.has(list.catId) ? map.get(list.catId).subCatArray.every(x => x.subCatId !== list.subCatId) ? map.get(list.catId).subCatArray.push(list) : null : map.set(list.catId, {
    catId: list.catId,
    catName: list.catName,
    subCatArray: []
  }) && map.get(list.catId).subCatArray.push(list), map), new Map()).values()];


let list = [{
    catId: "veg",
    catName: "vegetarian",
    subCatId: "potato",
    subcatName: "potatoes"
  },
  {
    catId: "veg",
    catName: "vegetarian",
    subCatId: "tomato",
    subcatName: "tomatoes"
  },
  {
    catId: "nonveg",
    catName: "Non vegetarians",
    subCatId: "chicken",
    subcatName: "chicken"
  },
  {
    catId: "apetizer",
    catName: "Apitizers",
    subCatId: "veg-apitizer",
    subcatName: "vegetarian Apitizers"
  }
]
console.log(catagoriseDuplicates(list));
.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}

closures using Reduce

const catagoriseDuplicates = list => list.reduce((hash => (map, list) => {
  !hash[list.catId] ? (hash[list.catId] = {
      _: []
    },
    map.push({
      catId: list.catId,
      catName: list.catName,
      subCatsArray: hash[list.catId]._
    })) : null;
  !hash[list.catId][list.subCatId] ? (hash[list.catId][list.subCatId] = list,
    hash[list.catId]._.push(list)) : null;
  return map
})(Object.create(null)), []);


let list = [{
    catId: "veg",
    catName: "vegetarian",
    subCatId: "potato",
    subcatName: "potatoes"
  }, {
    catId: "veg",
    catName: "vegetarian",
    subCatId: "potato",
    subcatName: "potatoes"
  },
  {
    catId: "veg",
    catName: "vegetarian",
    subCatId: "tomato",
    subcatName: "tomatoes"
  },
  {
    catId: "nonveg",
    catName: "Non vegetarians",
    subCatId: "chicken",
    subcatName: "chicken"
  },
  {
    catId: "apetizer",
    catName: "Apitizers",
    subCatId: "veg-apitizer",
    subcatName: "vegetarian Apitizers"
  }
]
console.log(catagoriseDuplicates(list));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.