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?
CodePudding user response:
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);
CodePudding user response:
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
CodePudding user response:
Maybe try something like this
for (var i = 0; i < source.length; i ) {
var item = source[i];
for (var j = i 1; j < source.length; j ) {
var item2 = source[j];
if (item.secondId === item2.secondId) {
item2.secondId = item.secondId "_" item2.id;
}
}
}
CodePudding user response:
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
- Use
.reduce
to iterate over the array of objects - Set up an initial
fin
object with two propstm
(tracking-map) andnewArr
(the result-array which will have thesecondId
updated as desired) - For each object, destructure to directly access
id
andsecondId
- Update the map
tm
based on thesecondId
with a counter - Append to the
newArr
an object withid
andsecondId
props with the latter (secondId
) being converted to a string to store values of the format1_2
,1_3
, etc
NOTE: This may not be an optimal solution.