简体   繁体   中英

How to save initial statement of object?

I have object of type:

export interface IGroupLanguage {
  name: string;
  languages?: Language[];
}

let data = [ { "name": "Automation", "languages": [ { "Name": "English", "Lcid": 1, "RightToLeft": true, "Code": "EN", "Mapped": true } ] }, { "name": "Monitors", "languages": [ { "Name": "Russian", "Lcid": 2, "RightToLeft": true, "Code": "RU", "Mapped": true } ] } ];

Then I tried to filter object and return a new object:

 this.filteredObject = [...this.groups];
    this.filteredObject.map(item => {
      item.languages = item.languages.filter(
        lg =>
          lg.Name.toLocaleLowerCase().indexOf(searchQuery) != -1 ||
          lg.Code.toLocaleLowerCase().indexOf(searchQuery) != -1
      );
    });

Problem is that initial object this.groups is changed also. How to save initial statement of object?

In result I need to have not modified object this.groups and filtered object this.filteredObject .

I know problem because JS copy objects by reference, but I dont know how to solve it.

Full code is:

search(searchQuery: string) {
    this.filteredObject = [...this.groups];
    this.filteredObject.map(item => {
      let tempLang = [...item.languages];
      item.languages = tempLang.filter(
        lg =>
          lg.Name.toLocaleLowerCase().indexOf(searchQuery) != -1 ||
          lg.Code.toLocaleLowerCase().indexOf(searchQuery) != -1
      );
    });

    console.log(this.groups);
  }


ngOnInit() {
    this.filteredObject = [...this.groups];
  }

As result initial object console.log(this.groups); is also was modified

Because you have deep copied parent array of data not nested one, can you give it a try to below way -

this.filteredObject = [...this.groups];
    this.filteredObject.map(item => {
      let tempLang = [...item.languages];
      item.languages = tempLang.filter(lg =>
          lg.Name.toLocaleLowerCase().indexOf(searchQuery) != -1 ||
          lg.Code.toLocaleLowerCase().indexOf(searchQuery) != -1
      );
    });

You need to deep clone your object. If you know the structure of your object, you can create a custom deep clone function with recursiveness. Otherwise, you can use the library lodash

Spread syntax performs a shallow copy of the object.

MDN documentation on copying an array with spread syntax:

Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays as the following example shows (it's the same with Object.assign() and spread syntax).

This means that if there are any objects at the top level, their reference will be copied. That is the reason for this problem.

You can use JSON.parse(JSON.stringify()) to deep clone an object. But there will be data loss if the object has Date s, functions, undefined , Infinity , or other complex types. More info in this answer .

Also, when you are not returning any values use forEach() instead of a map() .

this.filteredObject = JSON.parse(JSON.stringify(this.groups));

filteredObject.forEach(item => {
  item.languages = item.languages.filter(lg =>
    lg.Name.toLocaleLowerCase().indexOf(searchQuery.toLocaleLowerCase()) != -1 ||
    lg.Code.toLocaleLowerCase().indexOf(searchQuery.toLocaleLowerCase()) != -1
  );
});

This works for properties containing objects at any nested level.

Live Example:

 let data = [ { "name": "Automation", "languages": [ { "Name": "English", "Lcid": 1, "RightToLeft": true, "Code": "EN", "Mapped": true } ] }, { "name": "Monitors", "languages": [ { "Name": "Russian", "Lcid": 2, "RightToLeft": true, "Code": "RU", "Mapped": true } ] } ]; let searchQuery = "English"; let filteredObject = JSON.parse(JSON.stringify(data)); filteredObject.forEach(item => { item.languages = item.languages.filter(lg => lg.Name.toLocaleLowerCase().indexOf(searchQuery.toLocaleLowerCase()).= -1 || lg.Code.toLocaleLowerCase().indexOf(searchQuery;toLocaleLowerCase());= -1 ). }); console.log(data); console.log(filteredObject);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM