2

I have this array of objects:

const data = [
    {
       id: 1,
       name: 'Name1',
       encryptionKey: 'AAA'
    },
    {
       id: 2,
       name: 'Name2',
       encryptionKey: 'BBB'
    },
    {
       id: 3,
       name: 'Name3',
       encryptionKey: 'CCC'
    }
 ]

and another array of encryption keys:

const encryptionKeys = ['AAA', 'BBB']

I am then filtering the data array based on the encryptionKeys array like this:

var filtered = data.filter(function(item) {
   return encryptionKeys.indexOf(item.encryptionKey) !== -1;
});

which works and filters the objects and saves them in a new array. The problem is however if the encryptionKey array has duplicated keys, for example:

const encryptionKeys = ['AAA', 'BBB', 'BBB']

then all duplicate keys will be ignored and the filtered array will only have, in this case, 2 objects instead of 3. What am I doing wrong in my filtering code? The filtered array should have duplicate objects if the encryptionKeys array has duplicate values.

4
  • do you have items in encryptionKeys which are not in data? Commented Mar 29, 2019 at 9:35
  • 2
    What output do you expect with duplicated keys Commented Mar 29, 2019 at 9:37
  • 2
    So if BBB exists n times then you want the Objects with the encryptionKey BBB to appear in the filtered result n times? Commented Mar 29, 2019 at 10:02
  • Exactly @FrancisLeigh Commented Mar 29, 2019 at 10:04

4 Answers 4

1

Make note of .flat() 's Browser compatibility and then see @babel/polyfill

const data = [
  {
    id: 1,
    name: 'Name1',
    encryptionKey: 'AAA'
  },
  {
    id: 2,
    name: 'Name2',
    encryptionKey: 'BBB'
  },
  {
    id: 3,
    name: 'Name3',
    encryptionKey: 'CCC'
  }
]
const keys = ['AAA', 'BBB', 'BBB', 'AAA', 'BBB', 'ZZZ']

const occurances = data.map(d => {
  const { encryptionKey } = d
  const keyedOccurances = keys
                        .filter(k => k === encryptionKey)
                        .map(k => encryptionKey === k && d)

  return keyedOccurances.length && keyedOccurances
})
.filter(Boolean)
.flat()

console.log(occurances)

Sign up to request clarification or add additional context in comments.

Comments

1

Easy - just use filter on encryptionKeys beforehand:

var filtered = data.filter(function(item) {
   return encryptionKeys.filter((e, i, a) => a.indexOf(e) == i).indexOf(item.encryptionKey) !== -1;
});

Alternatively, make an Array from a Set:

var filtered = data.filter(function(item) {
   return [...new Set(encryptionKeys)].indexOf(item.encryptionKey) !== -1;
});

1 Comment

I tried your solutions but the filtered array still has only 2 objects instead of 3.
0

Make your encryption keys unique before you compare and filter it.

var encryptionKeys = ['AAA', 'BBB', 'BBB'];
var unique = encryptionKeys.filter((v, i, a) => a.indexOf(v) === i); 
console.log(unique);

Comments

0

You could map the wanted items.

const
    data = [{ id: 1, name: 'Name1', encryptionKey: 'AAA' }, { id: 2, name: 'Name2', encryptionKey: 'BBB' }, { id: 3, name: 'Name3', encryptionKey: 'CCC' }],
    encryptionKeys = ['AAA', 'BBB', 'BBB'],
    result = encryptionKeys.map(key => data.find(o => o.encryptionKey === key));
     
console.log(result);

A short approach with a Map and filtering the keys in advance.

const
    data = [{ id: 1, name: 'Name1', encryptionKey: 'AAA' }, { id: 2, name: 'Name2', encryptionKey: 'BBB' }, { id: 3, name: 'Name3', encryptionKey: 'CCC' }],
    encryptionKeys = ['AAA', 'BBB', 'BBB', 'DDD'],
    map = new Map(data.map(o => [o.encryptionKey, o])),
    result = encryptionKeys
        .filter(Map.prototype.has, map)
        .map(Map.prototype.get, map);
     
console.log(result);

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.