I've got a following array of objects
let views = [
{
name: "A View",
active: true,
},
{
name: "B View",
active: false,
},
{
name: "C View",
active: false,
}
];
When another elements are added, one by one with the existing name, for example another "A View", and another "A View" like for example
{
name: "A View",
active: true,
}
I want to add the suffix number to the name in the counting order, so I've got
[
{
name: "A View",
active: true,
},
{
name: "B View",
active: false,
},
{
name: "C View",
active: false,
},
{
name: "A View 2",
active: true,
}
]
after the first new "A View" added
And
[
{
name: "A View",
active: true,
},
{
name: "B View",
active: false,
},
{
name: "C View",
active: false,
},
{
name: "A View 2",
active: true,
},
{
name: "A View 3",
active: true,
}
];
after the second "A View" element added, and so on... Is I then remove "A View 2" I want the "2" suffix to be available to add for the new "A view" if I add it. So the next "A View" item will be "A View 2", not "A View 4"
This is my current solution
const addItem = (item) => {
views = [...views, item];
let names = {};
views.forEach((obj) => {
if (names[obj.name]) {
obj.name += " " + ++names[obj.name];
} else {
names[obj.name] = 1;
}
});
console.log("views", views);
};
The problem is that the suffix is not adding correctly. If I call the function 3 times passing the same object, like for example
addItem({
name: "A View",
active: true,
});
I will have this
Here is the working example - https://codesandbox.io/p/sandbox/8dhpl3
This seems to cover your requirement, although perhaps it can be optimised a little more.
Here, if a name or suffix exists, we iterate through the possible suffixes in ascending order until we get one that doesn't exist. For example, if A View
and A View 2
are already in views, we keep incrementing our suffix counter until we reach A View 3
which is available.
Note that even if we delete one in the middle, say the second one, leaving us with [A View
, A View 3
, A View 4
], we still fill A View 2
as required since we take the first available suffix.
let views = [
{
name: "A View",
active: true,
},
{
name: "B View",
active: false,
},
{
name: "C View",
active: false,
},
];
const addItem = (item) => {
let names = {};
views.forEach((obj) => {
names[obj.name] = 1;
});
let _suffix = "";
let _suffix_ctr = 1;
while (names[item.name + _suffix]) {
_suffix_ctr++;
_suffix = " " + _suffix_ctr;
}
let new_name = item.name + _suffix;
views = [...views, {...item, name: new_name}]
console.log("views", views);
};
addItem({
name: "A View",
active: true,
});
addItem({
name: "A View",
active: true,
});
addItem({
name: "A View",
active: true,
});