0

I am trying to sort an array. I wanted to sort it such that for the same accountID, I store all the items as an array item. Sample inputs:

[{accountID: "-Ks8mWWekpN2BfOFcdbS", itemName: "Petrol Charges At Esso"}],
[{accountID: "-Ks8mWWekpN2BfOFcdbS", itemName: "Hylo Lubricant Eye Drops 10ml"}],
[{accountID: "-Ks8mWWekpN2BfOFcdbS", itemName: "Genteal Gel, Sterile Lubricant Eye Gel, 10g"}],
[{accountID: "-Ks8mWWekpN2BfOFcdbS", itemName: "Genteal Gel, Sterile Lubricant Eye Gel, 10g"}],
[{accountID: "-Ks8mWWekpN2BfOFcdbS", itemName: "Blink Intensive Tears Protective Eye Drops 0.4mlx20"}],
[{accountID: "-Ks8mWWekpN2BfOFcdbS", itemName: "Palmers White And Even Dark Circles Eye Treatment Cream 15ml"}],
[{accountID: "-Ks8mWWq445Uao_9sgNn", itemName: "Sensitive Pro-relief With Whitening Toothpaste 110g"}],
[{accountID: "-Ks8mWWq445Uao_9sgNn", itemName: "2 In 1 Pure Breath Toothpaste"}],
[{accountID: "-Ks8mWWq445Uao_9sgNn", itemName: "Antibackterial Mouthwash 200ml"}],
[{accountID: "-Ks8mWWq445Uao_9sgNn", itemName: "Akira 1.7l Jug Kettle Jk1718c"}],
[{accountID: "-Ks8mWWq445Uao_9sgNn", itemName: "Duracell Alkaline Batteries Aaa 12s"}],
[{accountID: "-Ks8mWWq445Uao_9sgNn", itemName: "Osram Led Star Classic A100 Light Bulb - Frosted Warm White 10.5w/827"}],
[{accountID: "-Ks8mWWq445Uao_9sgNn", itemName: "Sharks Fin Soup With Crab Meat And Cordyceps"}],
[{accountID: "-Ks8mWWq445Uao_9sgNn", itemName: "Chilli Fried Rice With Shrimps"}],

enter image description here

Desired outputs to be printed to a text file:

['Petrol Charges At Esso', 'Hylo Lubricant Eye Drops 10ml', 'Genteal Gel, Sterile Lubricant Eye Gel, 10g', 'Blink Intensive Tears Protective Eye Drops 0.4mlx20', 'Palmers White And Even Dark Circles Eye Treatment Cream 15ml'],
['Sensitive Pro-relief With Whitening Toothpaste 110g', '2 In 1 Pure Breath Toothpaste', 'Antibackterial Mouthwash 200ml', 'Akira 1.7l Jug Kettle Jk1718c', 'Duracell Alkaline Batteries Aaa 12s', 'Osram Led Star Classic A100 Light Bulb - Frosted Warm White 10.5w/827', 'Sharks Fin Soup With Crab Meat And Cordyceps', 'Chilli Fried Rice With Shrimps'],

My code in JavaScript:

// for simplicity purpose, I do not post the chunk where I resolve the promise. 
promiseKey.then((arr) => {
console.log(arr);
            var result = arr.reduce(function(items, item) {
                var existing = items.find(function(i) {
                    return i.accountID === item.accountID;
                });

                if (existing) {
                    existing.filteredlist.push(item.itemName);
                } else {
                    items.push(item);
                }
            return items;
            }, []);
            console.log('filtered');
            console.log(result);
});

The error that I am getting is Uncaught (in promise) TypeError: Cannot read property 'push' of undefined at the else statement there.

  • can you show your array declaration – programtreasures Dec 21 '17 at 04:22
  • @programtreasures You mean 'arr' or 'filteredlist'? If 'arr', the data was previously retrieved from firebase. For simplicity purpose, I just console.log and format the input myself rather than post the whole chunk of retrieval. –  Dec 21 '17 at 04:24
  • @guest176969 Your input is not **an array**, it's **a bunch of arrays**. Choose one! – ibrahim mahrir Dec 21 '17 at 04:28
  • I have updated the question. Check the screenshot :) I might be formatting in the wrong way, I apologize for that! –  Dec 21 '17 at 04:29
  • The problem is that your `existing.filteredlist` filed is never created – Kirill Simonov Dec 21 '17 at 04:32

2 Answers2

2

You can take a more simplistic approach using a foreach loop and an object.

var items = {};

arr.forEach(function(item) {

    if(!items.hasOwnProperty(item.accountID)) {
        items[item.accountID] = [];
    }

    items[item.accountID].push(item.itemName);
});

You can use Object.keys(items) to get the keys of each account.

Object.keys(items).forEach(function(account) {
    // account is the accountID

    var accountItems = items[account];
});
Nick Tucci
  • 336
  • 4
  • 16
  • I am getting accountID of undefined error message :( –  Dec 21 '17 at 04:39
  • I have tested on my end and it works on my side. The problem must be the underlying promise. – Nick Tucci Dec 21 '17 at 04:40
  • I managed to print out the data in arr though so I don't think it's related to the promise. –  Dec 21 '17 at 04:42
  • Try removing the `[0]` from itemArray. – Nick Tucci Dec 21 '17 at 04:44
  • It works with the version where you put the const items = {}; But then when I put a for loop trying to access 'items' nothing was printed out. It only printed out the sorted array together with its accountID without the for loop –  Dec 21 '17 at 04:45
  • I edited my post with an example to access items – Nick Tucci Dec 21 '17 at 04:50
  • Please use the updated version. I made a mistake previously. – Nick Tucci Dec 21 '17 at 04:57
  • Cool thanks so much!! –  Dec 21 '17 at 05:00
  • Hey let's say if I got another field called receiptID. Then, I wanted to sort by accountID, followed by receiptID and store the item in the same way. How can I actually achieve this? Just add another if condition in the first forEach will suffice? –  Dec 21 '17 at 05:47
1

Here you need to initialize before filteredlist use

updated code

console.log(arr);
            var result = arr.reduce(function(items, item) {
                var existing = items.find(function(i) {
                    return i.accountID === item.accountID;
                });

                if (existing) {                  
                   existing.filteredlist = [];
                    existing.filteredlist.push(item.itemName);
                } else {
                    items.push(item);
                }
            return items;
            }, []);
            console.log('filtered');
            console.log(result);

here is my jsbin demo https://jsbin.com/tepedut/edit?js,console

EDIT :

As per your comment you need to sort arr with accountID property, you can use javascript arr.sort(function(a, b){}); function to sort the array.

here is updated code

arr.sort(function(a, b){
   if(a.accountID < b.accountID) return -1;
    if(a.accountID > b.accountID) return 1;
    return 0;
});

console.log(arr);

updated js bin https://jsbin.com/tepedut/8/edit?js,console

programtreasures
  • 4,250
  • 1
  • 10
  • 29
  • Is there anyway to print out the itemName as desired output? Because currently the console.log(result) is printing out with the accountID as well –  Dec 21 '17 at 04:38
  • check this updated js bin added `item.itemName` to array https://jsbin.com/tepedut/5/edit?js,console – programtreasures Dec 21 '17 at 04:40
  • But if that's the case it just push every single item regardless of the accountID into a single array. Is there any way to separate it such that each accountID printed out as per the desired output? –  Dec 21 '17 at 04:44
  • do you need to also return accountID in result ? – programtreasures Dec 21 '17 at 04:47
  • Nope nope, I only need the items sorted by each accountID as per the desired output part –  Dec 21 '17 at 04:48
  • please check updated answer – programtreasures Dec 21 '17 at 04:55