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; }