I have an array "source"
source : [
{
"id": 1,
"secondId": 1
},
{
"id": 2,
"secondId": 1
},
{
"id": 3,
"secondId": 1
}
]
I want to rename the secondId when there are duplicate like this:
[
{
"id": 1,
"secondId": 1
},
{
"id": 2,
"secondId": 1_2
},
{
"id": 3,
"secondId": 1_3
}
]
I have this so far:
for (i = 0 ; i < source.length ; i++) {
for (j = 0 ; j < source.length ; j++){
if (source[i]["id"] != source[j]["id"] && source[i]["secondId"] === source[j]["secondId"]){
source[j]["secondId"] += "_" + (i+1);
}
console.log(source[j]["secondId"]);
}
}
and I'm getting:
[
{
"id": 1,
"secondId": 1
},
{
"id": 2,
"secondId": 1_2
},
{
"id": 3,
"secondId": 1_2_3
}
]
I tried to use some:
if(source[j]["secondId"].includes("_"+ (i+1))){
console.log(source[j]["secondId"].split("_"+ (i+1)).shift());
}
but I'm getting:
"secondId": 1 "secondId": 1 "secondId": 1_2
How can I do it? Any tips please?
A version using Array.reduce:
let source = [
{
"id": 1,
"secondId": 1
},
{
"id": 2,
"secondId": 1
},
{
"id": 3,
"secondId": 1
}];
let output = Object.values(
source.reduce((a, e, i) => {
let testId = e.secondId.toString();
if (a[testId]) {
testId = testId.split("_")[0] + "_" + (i + 1);
}
a[testId] = {...e, secondId: testId};
return a;
}, {})
);
console.log(output);
This may be a solution to achieve the (assumed) desired objective:
Code Snippet
const markDupes = arr => (
arr.reduce(
(fin, {id, secondId}) => ({
tm: {
[secondId]: (fin.tm[secondId] || 0) + 1
},
newArr: [
...fin.newArr,
{id, secondId: secondId.toString() + (
fin.tm[secondId] > 0 ? `_${fin.tm[secondId]+1}` : ''
)}
]
}),
{ tm: {}, newArr: [] }
)?.newArr
);
const source = [{
"id": 1,
"secondId": 1
},
{
"id": 2,
"secondId": 1
},
{
"id": 3,
"secondId": 1
}
];
console.log(markDupes(source));
Explanation
.reduce to iterate over the array of objectsfin object with two props tm (tracking-map) and newArr (the result-array which will have the secondId updated as desired)id and secondIdtm based on the secondId with a counternewArr an object with id and secondId props with the latter (secondId) being converted to a string to store values of the format 1_2, 1_3, etcNOTE: This may not be an optimal solution.
When you convert 1 to 1_2 or 1_3 it is converting a number to a string which will be a huge pain when you have a use for the number later. Instead what i have done is convert that number to a decimal for as 1.2 ,1.3 which means you can do all sorts of computation on a number without much conversion
let source = [
{
"id": 1,
"secondId": 1
},
{
"id": 2,
"secondId": 1
},
{
"id": 3,
"secondId": 1
}
];
let val = {};
for (const i in source) {
let v = source[i].secondId
val[v] = val[v] ? val[v] : v
if (val[v] !== 1) {
console.log(source[i].id, v);
source[i].secondId = Number(v.toFixed(2)) + (val[v] * 0.1)
}
val[v]++
}
console.log(source);
if you are really kean of using string instead use
source[i].secondId = v+'_'+val[v]instead inside the if by changing the original source json object as well