Reputation:
I want to add the elements of my new list (newList) to my already existing list (oldList), but before inserting I must verify if my element of my newList already exists in my oldList, in case it does, an extra number must be added.
let newList = [{name: "abc.jpeg"}, {name: "abc.jpeg"}]
let oldList = [{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa.jpeg"},
{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa1.jpeg"},
{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa2.jpeg"}]
const addElement = (colection, new_item, tally) => {
const a = new_item.name.split('.')
const reps = colection.filter(elem => {
var reg = /.*2Fpictures%2F(.*)/
const name = elem.name.match(reg)
if(name)
return name[1].includes(a[0])
}).length
new_item.sname = a[0] + (reps > 0 ? reps : '') + '.' + a[1]
colection.push(new_item)
console.log(colection)
return colection
}
let tally = {}
for (let index = 0; index < newList.length; index++) {
oldList = addElement(oldList, newList[index], tally)
}
[{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa.jpeg"},
{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa1.jpeg"},
{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa2.jpeg"},
{name: "abc.jpeg"},
{name: "abc1.jpeg"}]
because the three element contain "fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fabc.jpeg"
the abc.jpeg
Upvotes: 0
Views: 105
Reputation: 819
//I added some element for testing
let newList = [
{name: "abc.jpeg"},
{name: "abc.jpeg"},
{name:"xxx123.jpg"},
{name:"xxx123.jpg"},
{name:"xxx123.jpg"},
{name:"xxx123.jpg"},
{name:"yyy143.jpg"},
{name:"yyy143.jpg"},
{name:"yyy143.jpg"},
{name:"yyy144.jpg"},
{name:"yyy145.jpg"},
{name:"yyy146.jpg"}
];
let oldList = [
{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa.jpeg"},
{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa1.jpeg"},
{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa2.jpeg"}];
//Creating a Set
const mySet = new Set()
//Fill mySet with files names
for (i=0;i<oldList.length;i++){
mySet.add(oldList[i].name);
}
//Looping newList
for (i=0;i<newList.length;i++){
if (mySet.has(newList[i].name)){
// The point "." position in filename string
pointpos = newList[i].name.lastIndexOf(".");
// File name and file extension
name = newList[i].name.substring(0,pointpos);
ext = newList[i].name.substring(pointpos);
// Getting numbers in file name string from right to left
// initializing cursor pos at the end of the file name string
pos=name.length-1;
//Where to store the numbers of the file name , if any .
numbers=[];
// String numbers 0,1,2,3,4,5,6,7,8,9
// have char codes from 48 to 57
while ( 48 <= name.charCodeAt(pos) && 57 >= name.charCodeAt(pos) && pos >= 0){
//Add values at top of the array , not at bottom.
numbers.unshift(name.charAt(pos));
pos--;
}
//if file name has numbers...
if (numbers.length > 0){
//join numbers and sum 1
num = parseInt(numbers.join(""))+1;
snum = String(num);
// name without numbers part
name = name.substring(0,name.length-numbers.length);
//Sum 1 again while we have a filename in the Set
while (mySet.has(name+snum+ext)){
snum=String(num++);
}
//Here we have a new file name not present in the Set
//So add it to the Set with number and extension
mySet.add( name+snum+ext);
}else{
//The file name is duplicate but
//there are no others with numbers
//so add "1" string to the name and extension
//and add it to the Set
name+="1";
mySet.add(name+ext);
}
}else{
// The filename is not present in oldlist so we can add it in the Set
mySet.add(newList[i].name);
}
}
//Reset oldList array
oldList=[];
//Fill it with objects like it was but with new set items as values
for (let item of mySet) {
oldList.push({name:item})
}
//Show it
console.log(oldList);
Without comments:
const mySet = new Set();
for (i=0;i<oldList.length;i++)mySet.add(oldList[i].name);
for (i=0;i<newList.length;i++){
if (mySet.has(newList[i].name)){
pointpos = newList[i].name.lastIndexOf(".");
name = newList[i].name.substring(0,pointpos);
ext = newList[i].name.substring(pointpos);
pos=name.length-1;
numbers=[];
while ( 48 <= name.charCodeAt(pos) && 57 >= name.charCodeAt(pos) && pos >= 0){
numbers.unshift(name.charAt(pos));
pos--;
}
if (numbers.length > 0){
num = parseInt(numbers.join(""))+1;
snum = String(num);
name = name.substring(0,name.length-numbers.length);
while (mySet.has(name+snum+ext)){
snum=String(num++);
}
mySet.add( name+snum+ext);
}else{
name+="1";
mySet.add(name+ext);
}
}else{
mySet.add(newList[i].name);
}
}
oldList=[];
for (let item of mySet) {
oldList.push({name:item})
}
console.log(oldList);
Upvotes: 1
Reputation: 171679
Another approach using what you started with a tally
that is a Map and is far more efficient for lookups than using multiple instances of filter()
let newList = [{name: "abc.jpeg"}, {name: "abc.jpeg"},{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa.jpeg"}]
let oldList = [{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa.jpeg"},
{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa1.jpeg"},
{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa2.jpeg"}, {name: "abc.jpeg"}];
const baseName = (str) => str.replace(/\d+\./, '.');
const getNamesCount = arr => arr.reduce((a,{name})=>{
const base = baseName(name);
return a.set(base, (a.get(base)||0)+1)
},new Map())
const mergeLists = (oList, nList) => {
const tally = getNamesCount(oList);
nList.forEach(({name,...rest})=>{
const base = baseName(name);
if(tally.has(base)){
let count = tally.get(base)
name = name.split('.').join(count + '.');
tally.set(base, ++count)
}else{
tally.set(base, 1)
}
oList.push({name,...rest})
})
return oList;
}
console.log(mergeLists(oldList,newList))
Upvotes: 1
Reputation: 1167
You can find occurence of the string initially and then append that number to the string.
let newList = [{name: "abc1.jpeg"}, {name: "abc1.jpeg"}]
let oldList = [{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa.jpeg"},
{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa1.jpeg"},
{name:"fs%2FPanel%8SmgM7rhJ4T9j%2Fpictures%2Fa2.jpeg"}]
const addElement = (colection, new_item, tally) => {
const a = new_item.name.split('.')
const occurence = colection.filter(item=>item.name===new_item.name).length;
if(occurence>0){
const firstPart =[...a.slice(0,-1)].join(".");
const digitMatch = firstPart.match(/(\d+)$/);
const digitString = digitMatch && digitMatch[0];
const firstPartWithoutDigit =digitString && firstPart.slice(0,-digitString.length )
const digit = digitString && parseInt(digitString);
const newDigit = (digit || 0) + occurence;
const prefix = firstPartWithoutDigit || firstPart;
new_item.name = prefix+ newDigit +"." +a[a.length-1]
//[...a.slice(0,-1)].join(".") -> Part Before Last .
// occurence-> Number of times filename exists in the collection
//a[a.length-1] -> Last part of string after .
}
const reps = colection.filter(elem => {
var reg = /.*2Fpictures%2F(.*)/
const name = elem.name.match(reg)
if(name)
return name[1].includes(a[0])
}).length
new_item.sname = a[0] + (reps > 0 ? reps : '') + '.' + a[1]
colection.push(new_item)
console.log(colection)
return colection
}
let tally = {}
for (let index = 0; index < newList.length; index++) {
oldList = addElement(oldList, newList[index], tally)
}
Upvotes: 0