I'm currently trying to build an addOrUpdate function
.
Unfortunately I failed several times.
Basically, I have an array of objects. Each object in turn has an array of strings
values
(and a key valueGroup
).
First you have to check if the object exists, if not a new one should be added. If the object already exists, I want to check whether the value I want to insert is already in the object's string array. If not add it. Is it there delete it!
I first tried it functionally via mapper, but I failed completely because I got a double array. Of course, it would be best to solve it completely functionally. Is it possible?
Currently there is no update of the objects. A new object is always inserted, again with an array string containing a new value.
I also find the current code too complicated
I am using Typescript
type SelectedValues = {
valueGroup: string;
values: string[];
};
function updateSelectedValues(selectedValues: SelectedValues[], valueGroup: string, value: string): SelectedValues[] {
// If array empty add first object
if (selectedValues.length === 0) {
return [{ valueGroup: valueGroup, values: [value] }];
} else {
// look if valueGroup is already there
const index = selectedValues.findIndex((find) => find.valueGroup === valueGroup);
if (index === -1) {
// if no add new valueGroup with first values
return [...selectedValues, { valueGroup: valueGroup, values: [value] }];
} else {
// if valueGroup is there, look if value is already in values
const findedValues = selectedValues[index];
if (findedValues.values.includes(value)) {
// yes, remove value from values
return [...selectedValues, { ...findedValues, values: findedValues.values.filter((filter) => filter !== value) }];
} else {
// no, add value to values
return [
...selectedValues.filter((object) => object.valueGroup === valueGroup),
{ ...findedValues, values: [...findedValues.valueGroup, value] },
];
}
}
}
}
I always click a button. The button passes the values (valueGroup and value)
through the OnClick handler. The array should update itself according to my explanation. Here is an example of how that array could change
//Imagine, after some time we are here. At first it was empty. Two groups were inserted and filled
type SelectedValues = [
{
valueGroup: "valueGroupOne",
values: ["some", "more", "example", ]
},
{
valueGroup: "valueGroupTwo",
values: ["ddd", "sss", "aaa", ]
}
]
// And new group
type SelectedValues = [
{
valueGroup: "valueGroupOne",
values: ["some", "more", "example", ]
},
{
valueGroup: "valueGroupTwo",
values: ["ddd", "sss", "aaa", ]
},
valueGroup: "valueGroupThree",
values: ["ssss", "dddsd", "adsdas", ]
}
]
// add to an existing Group new value
type SelectedValues = [
{
valueGroup: "valueGroupOne",
values: ["some", "more", "example","newValueadded" ]
},
{
valueGroup: "valueGroupTwo",
values: ["ddd", "sss", "aaa", ]
},
valueGroup: "valueGroupThree",
values: ["ssss", "dddsd", "adsdas", ]
}
]
// delete from existing Group value
type SelectedValues = [
{
valueGroup: "valueGroupOne",
values: ["some", "more", "example" ]
},
{
valueGroup: "valueGroupTwo",
values: ["ddd", "sss", "aaa", ]
},
valueGroup: "valueGroupThree",
values: ["ssss", "dddsd", "adsdas", ]
}
]
CodePudding user response:
You can achieve this with the help of few JavaScript methods :
Array.some()
- Used to check if object exist or not based on the key.Array.forEach()
- Used to iterate the original array to add/update the value.Array.includes()
- Used to check if values array contains the value which we want to insert or not.Array.splice()
- Used to remove the value if exist.Array.push()
- Used to push the value in values array if not exist / push the object itself if not exist.
Live Demo :
const arr = [{
valueGroup: 'Group 1',
values: ['Value 1', 'Value 2']
}, {
valueGroup: 'Group 2',
values: ['Value 3', 'Value 4']
}, {
valueGroup: 'Group 3',
values: ['Value 5', 'Value 6']
}];
const searchObj = {
valueGroup: 'Group 2',
values: ['Value 4']
};
const objectExist = arr.some(obj => obj.valueGroup === searchObj.valueGroup);
if (objectExist) {
arr.forEach(obj => {
if (obj.values.includes(searchObj.values[0])) {
obj.values.splice(obj.values.indexOf(searchObj.values[0]), 1)
} else {
obj.values.push(searchObj.values[0])
}
});
} else {
arr.push(searchObj);
}
console.log(arr);
CodePudding user response:
You were already pretty close, just made some small errors like not filtering out the object you want to update from the array. I did also change it to use find
instead of findIndex
but it does not make a huge difference.
function updateSelectedValues(selectedValues: SelectedValues[], valueGroup: string, value: string): SelectedValues[] {
// If array empty add first object
if (selectedValues.length === 0) {
return [{ valueGroup: valueGroup, values: [value] }];
} else {
// look if valueGroup is already there
const obj = selectedValues.find((find) => find.valueGroup === valueGroup);
if (!obj) {
// if no add new valueGroup with first values
return [...selectedValues, { valueGroup: valueGroup, values: [value] }];
} else {
if (obj.values.includes(value)) {
// yes, remove value from values
return [...selectedValues.filter((object) => object.valueGroup !== valueGroup), { ...obj, values: obj.values.filter((filter) => filter !== value) }];
} else {
// no, add value to values
return [
...selectedValues.filter((object) => object.valueGroup !== valueGroup),
{ ...obj, values: [...obj.values, value] },
];
}
}
}
}
This Playground has some tests to see the functionality.
CodePudding user response:
I wrote a function that takes 2 parameters (array with SelectedValues && object with data to add/edit/remove) :
let data = [{
valueGroup: "valueGroupOne",
values: ["some", "more", "example", ]
},
{
valueGroup: "valueGroupTwo",
values: ["ddd", "sss", "aaa", ]
}
];
function addOrEdit(arr, valueGroup, values) {
let valueGroupIdx = arr.findIndex(el => el.valueGroup == valueGroup);
if(valueGroupIdx > -1) {
arr[valueGroupIdx].values = [
...arr[valueGroupIdx].values.filter(v => !values.includes(v)),
...values.filter(v => !arr.at(valueGroupIdx).values.includes(v))
];
} else {
arr.push(obj);
}
}
addOrEdit(data, 'valueGroupTwo', [1, 2, 'sss']);
addOrEdit(data, 'valueGroupThree', ['aaa', 'bbb', 'sss']);
console.log(data);