Home > Mobile >  Parent object changes even if the copy of it is created while splice
Parent object changes even if the copy of it is created while splice

Time:07-14

I have a parent object categories, and a function that flattens and removes duplicate numbers inside the array. But even though I make a copy the categories object (let newObj = {...categories}) and perform the above flatten function, it affects the parent categories object.

Code:

let categories = {
  Red: {
    Name: "Fire Flame",
    List: [
      ["1","5"],
      ["10","15"]
    ]
  },
  Blue: {
    Name: "Super Light",
    List: [
      ["1","5"],
      ["9","12"]
    ]
  },
  Custom: {
    List: [
      "Star Flash"
    ]
  }
}



  const submitData = () => {
    let obj = { ...categories };
    let types = Object.keys(obj);
    types.map((key) => {
      flattenAndUnique(key);
    });
    function flattenAndUnique(key) {
      let myList = obj[key].List;
      let resList = [];
      if (key !== "Custom") {
        myList.map(async (data, index) => {
          let min = Math.min(...data);
          let max = Math.max(...data);
          for (let i = min; i <= max; i  ) {
            resList.push(String(i));
          }
          const spliced = [...myList.splice(index, 1, resList)];
          let flatLevelArray = [].concat.apply([], myList);
          let uniqueLevelArray = flatLevelArray.filter(
            (v, i, a) => a.indexOf(v) === i
          );
          obj = {
            ...obj,
            [key]: {
              ...obj[key],
              List: uniqueLevelArray,
            },
          };
          resList = [];
        });
      } else {
        let flatLevelArray = [].concat.apply([], myList);
        obj = {
          ...obj,
          Custom: {
            ...obj.Custom,
            List: flatLevelArray,
          },
        };
      }
    }
    console.log("final obj %% ===>", obj);
    console.log("Floors final &&&&", categories);
  };
  
  submitData()

sumbitData function actually flattend the array and removes duplicates. For eg, If i have two array - [["1","4"] , ["11","13"]], the function transforms it into - ["1","2","3","4","11","12","13"] which works fine, My only issue is that my parent categories also changes.

CodePudding user response:

First of all, you get the reference of the List property.

let myList = obj[key].List;

And then in the bottom, you splice it. ( splice will effect the origin array as it has the same referance )

const spliced = [...myList.splice(index, 1, resList)];

It should be

let myList = [...obj[key].List];

CodePudding user response:

You do not need shallow copy or deep copy. Simply traverse the input object and yield the desired values. Traversal is a read operation and should not modify the input. Use a generic unique function to filter non-unique values out. As you can see categories is not changed as a result of running our code.

function *toFlat(t) {
  switch (t?.constructor) {
    case Object:
      for (const v of Object.values(t))
        if (Object(v) === v)
          yield *toFlat(v)
      break
    case Array:
      for (const v of t)
        yield *toFlat(v)
      break
    default:
      yield t
  }
}

function unique(t) {
  const s = new Set
  for (const v of t)
    s.add(v)
  return Array.from(s)
}

let categories =
  {Red:{Name:"Fire Flame",List:[["1","5"],["10","15"]]},Blue:{Name:"Super Light",List:[["1","5"],["9","12"]]},Custom:{List:["Star Flash"]}}


console.log(unique(toFlat(categories)))
console.log(categories)
.as-console-wrapper { min-height: 100%; top: 0; }

  • Related