0

I was having some problem when trying to check for duplicate by multiple fields before inserting into the array. What I am trying to do is retrieve from firebase, check for accountID and subtype fields before inserting into the array to be resolved by Promise.

What I trying to achieve is If same accountID, different subtype, then I add; If same accountID, same subtype, I move to next; If different accountID, different subtype, I add. Here is my code:

code:

var datasetarr = [];
let promiseKey = new Promise((resolve, reject) => {
                for(var i = 0; i < receiptlist.length; i++){
                    for(var k = 0; k < ritemlist.length; k++){
                        if(receiptlist[i].date.substring(0, 4) == new Date().getFullYear()){
                            if(ritemlist[k].receiptID == receiptlist[i].receiptID){
                              //check duplicate here before insert
                                if (!datasetarr.find(o => o.accountID === receiptlist[i].accountID && o.subtype === ritemlist[k].type))
                                    datasetarr.push({accountID: receiptlist[i].accountID, subtype: ritemlist[k].type});
                                }
                            }
                        }
                    }
                }
            resolve(datasetarr);
            });

The part when I tried to print out the array:

array:

promiseKey.then((arr) => {
            console.log(arr);
});

The output I am getting:

output:

enter image description here

I still see a lot of duplicate with same accountID and same subtype. Is there anyway to resolve this?

Thanks!

Dilip
  • 2,622
  • 1
  • 20
  • 27
QWERTY
  • 2,303
  • 9
  • 44
  • 85
  • you can use lodash `_.some([{"a": 1}, {"b": 2}], {"b": 2}) ` – zabusa Dec 21 '17 at 07:13
  • 1
    Possible duplicate of [Remove Duplicate objects from JSON Array](https://stackoverflow.com/questions/23507853/remove-duplicate-objects-from-json-array) – Hassan Imam Dec 21 '17 at 07:14
  • 1
    We can't help without an example of the input data. – T.J. Crowder Dec 21 '17 at 07:20
  • @T.J.Crowder The input data is exactly same as the output. I have no idea why the if statement before insert is not checking properly :( – QWERTY Dec 21 '17 at 07:21
  • @hyperfkcb: It clearly isn't, as it 1. Is two separate arrays/lists (`recipientList` and `ritemlist`), and 2. Has properties like `date`. – T.J. Crowder Dec 21 '17 at 07:22
  • Is `receiptlist[i].date` a String? – Roman Dec 21 '17 at 08:05
  • Under the [repl](https://repl.it/repls/SurprisedBlindBellfrog) your loop works like expected. could you provide more details.. for example input data – Roman Dec 21 '17 at 08:39

3 Answers3

0

find return undefined if there is no occurrence of your data; so what you have to do is to check whether the value returned is undefined and then you do your computation

  var found = datasetarr.find(o => o.accountID === receiptlist[i].accountID && o.subtype === ritemlist[k].type)
     if (found === undefined){
         //do computation
     }
edkeveked
  • 17,989
  • 10
  • 55
  • 93
  • @hyperfkcb What do you have in type ? – edkeveked Dec 21 '17 at 07:18
  • The data from the screenshot! Like for example the first accountID has fueld then eyecare, eyecare, eyecare ... – QWERTY Dec 21 '17 at 07:19
  • Cool that works! But may I know why by declaring a new variable solve the problem? – QWERTY Dec 21 '17 at 07:29
  • @hyperfkcb, it is not working because of declaring a new variable but because of the check against undefined that you were not doing before – edkeveked Dec 21 '17 at 07:31
  • 1
    @hyperfkcb: Your code was `if (!find(...))`, which will be true if `find` returns `undefined`. This cannot be the correct answer. – T.J. Crowder Dec 21 '17 at 07:39
  • @T.J.Crowder, he would like to add the current item if it is not already in the array. What my answer is doing is to use find(). And the item will be added only if what is returned is undefined. Otherwise it means that the items already exists. – edkeveked Dec 21 '17 at 07:43
  • 1
    @edkeveked: Right. And his code does that too. Assuming the entries in the array are not falsy values (and his appear to be objects), `!find.(...)` and `find(...) === undefined` do the same thing. – T.J. Crowder Dec 21 '17 at 07:56
  • @T.J.Crowder Why not editing the answer, if you consider that could help. I think the `undefined` has to be checked explicitly and not with a `!` condition. For instance: `var a ; if(!a){console.log(a)}` will print `undefined` because the check against undefined did not work out whereas `var a ; if(a !== undefined){console.log(a)}` will not print anything. – edkeveked Dec 21 '17 at 08:12
  • @edkeveked: *"I think the undefined has to be checked explicitly and not with a ! condition"* Well, you're mistaken about that; the concept of "truthiness" and "falsiness" is basic JavaScript. Regarding your two code examples: They check opposite conditions, of course they work differently. You're using `===` in the answer, not `!==`. The OP's using `!`. If their code doesn't work, yours won't. I'm not editing the answer (or answering the question) for the reasons I gave in my comments on the question. Until/unless the OP provides input data, the question cannnot be usefully answered. – T.J. Crowder Dec 21 '17 at 08:17
  • 1
    The solution is working as I can see my output being filtered as per desired. Why down vote though? – QWERTY Dec 21 '17 at 08:44
0

You can use lodash which is very good library for array handling.

in your case data should be unique by accountId and your data is stored in data variable, you can use _.uniqBy() function like this:

jvar datasetarr = []; 
  let promiseKey = new Promise((resolve, reject) => {
            for(var i = 0; i < receiptlist.length; i++){
                for(var k = 0; k < ritemlist.length; k++){
                    if(receiptlist[i].date.substring(0, 4) == new 
                       Date().getFullYear()){
                        if(ritemlist[k].receiptID == receiptlist[i].receiptID){
                                  //Push your object here.
                                datasetarr.push({accountID: receiptlist[i].accountID, subtype: ritemlist[k].type});
                            }
                        }
                    }
                }
            }

           //Before resolving check for the duplicates.
            _.uniqBy(datasetarr, function (data) {
                return data.accountID;
             });

            resolve(datasetarr);
        });
0

let arr = ["Apple", "Orange"]
let newElement = "Apple"

if (!arr.includes(newElement)) arr.push(newElement)
else console.log("Element is already there")
console.log("Array Elements : " + arr)

Looking for other suitable methods for the same functionality.

Zero
  • 2,164
  • 1
  • 9
  • 28