user15570208
user15570208

Reputation:

How can i rename elements before to insert it?

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)
}
the expected result I need is this:

[{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

Answers (3)

Mario Abbruscato
Mario Abbruscato

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

charlietfl
charlietfl

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

Cybershadow
Cybershadow

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

Related Questions