Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter nested object

I receive an object that looks like this:

 this.tokensData = {
    O: {
        id: 0,
        name: value1,
        organization: organization1,
        ...,
       },
    1: {
        id: 1,
        name: value1,
        organization: organization1,
        ...,
        },
    2: {
        id: 2,
        name: value2,
        organization: organization2,
        ...,
        },
    ...
   }

I want to filter by id and remove the Object which id matches the id I receive from the store. What I tried so far:

const filteredObject = Object.keys(this.tokensData).map((token) => {
  if (this.$store.state.id !== this.tokensData[token].id) {
    return this.tokensData[token];
  }
});

This replaces the Object with undefined - which would work for my purposes but is obviously not ideal. Any help is much appreciated!

like image 640
suuuriam Avatar asked Apr 15 '20 13:04

suuuriam


People also ask

Can I use filter in object?

JavaScript's Objects are not iterable like arrays or strings, so we can't make use of the filter() method directly on an Object .

How do you filter an object in JavaScript?

Unfortunately, JavaScript objects don't have a filter() function. But that doesn't mean you can't use filter() to filter objects, you just need to be able to iterate over an object and convert the object into an array using Object. entries() .

What is nested object in JavaScript?

Nested objects are objects that are inside another object. You can create nested objects within a nested object. In the following example, Salary is an object that resides inside the main object named Employee . The dot notation can access the property of nested objects. JavaScript.

Can you filter an array of objects?

One can use filter() function in JavaScript to filter the object array based on attributes. The filter() function will return a new array containing all the array elements that pass the given condition. If no elements pass the condition it returns an empty array.


4 Answers

Try to use Object.entries and then Object.fromEntries() to create an object from a list of key-value pairs:

let store = [0 , 1];

const result = Object.entries(tokensData).filter(([k, v]) => !store.some(s => s == v.id));

console.log(Object.fromEntries(result));

An example:

let tokensData = {
   O: {
       id: 0,
       name: '',
       organization: '',
      },
   1: {
       id: 1,
       name: '',
       organization: '',
       },
   2: {
       id: 2,
       name: '',
       organization: '',
       }
  }

let store = [0 , 1];

const result = Object.entries(tokensData).filter(([k, v]) => !store.some(s => s == v.id));

console.log(Object.fromEntries(result));
like image 83
StepUp Avatar answered Sep 28 '22 03:09

StepUp


You can do this by using Object.entries and Object.fromEntries:

const filteredObject = Object.fromEntries(
  Object.entries(this.tokensData).filter(
    ([key, value]) => value.id !== this.$store.state.id
  )
)
like image 29
Stefan Bajić Avatar answered Sep 28 '22 03:09

Stefan Bajić


This can be done by cloning the object and removing the object at the ID:

const removeObjectByID = (obj, id) => {
  // first create a copy of the object
  const copy = JSON.parse(JSON.stringify(obj))
  // next, delete the one entry you don't want
  delete copy[id]
  // finally, return the new object
  return copy
}

// Test
const data = {a:1, b: 2, c: 3}

console.log(removeObjectByID(data, 'b')) // { a: 1, c: 3 }
like image 37
Rob Brander Avatar answered Sep 28 '22 02:09

Rob Brander


The problem with undefined is caused by using this in your arrow function. Javascript scoping gives a different meaning to this if the function is a arrow function.

Furthermore I suggest to use filter.

.map is used to transform A -> B.

.filter should be used to filter out objects.

Now if we combine that this would become something like this.

function filterById(token) {
  return this.$store.state.id !== this.tokensData[token].id;
}

function getTokenData(token) {
  return this.tokensData[token]
}

const token = Object.keys(this.tokensData)
  .filter(filterById)
  .map(getTokenData);
});

Please note that I'm not using arrow functions. Arrow function can't refer to this due to the way javascript handles scoping.

An alternative approach could be to reference this into a variable, so your arrow function can access the variable.

const self = this;
const token = Object.keys(this.tokensData)
  .filter(token => self.$store.state.id !== self.tokensData[token].id)
  .map(token => self.tokensData[token]);

Too make it even nicer you could utilize Object.entries. This will return an array of key and value, which you can destructure using es6 syntax as following [key, value].

const self = this;
const token = Object.entries(this.tokensData)
  .filter(([key, value]) => self.$store.state.id !== value.id)
  .map(([key, value]) => value);
like image 45
Marco Avatar answered Sep 28 '22 02:09

Marco