简体   繁体   中英

How to move object inside another object in the same array

I have 3 arguments in a move function those are list,source and destination. List is here:

const list = [
      {
        id: '1',
        name: 'Folder 1',
        files: [
          { id: '2', name: 'File 1' },
          { id: '3', name: 'File 2' },
          { id: '4', name: 'File 3' },
          { id: '5', name: 'File 4' },
        ],
      },
      {
        id: '6',
        name: 'Folder 2',
        files: [{ id: '7', name: 'File 5' }],
      },
    ];

in a given function I should enter the source and destination and I could move for example move(list, '4', '6') then I expect file with id 4 moved to the folder which has id 6 .

Like that:

const result = [
  {
    id: '1',
    name: 'Folder 1',
    files: [
      { id: '2', name: 'File 1' },
      { id: '3', name: 'File 2' },
      { id: '5', name: 'File 4' },
    ],
  },
  {
    id: '6',
    name: 'Folder 2',
    files: [
      { id: '7', name: 'File 5' },
      { id: '4', name: 'File 3' },
    ],
  },
];

I moved it Received: {"files": [{"id": "7", "name": "File 5"}, {"id": "4", "name": "File 3"}], "id": "6", "name": "Folder 2"} but I couldn't delete the value that id is 4.

Here is my code

let copyList =list.slice();

 const filteredVal =  copyList[0].files.find((file: { id: Object; })=> { 

  return file.id == source
 } );// 2-3-4-5

//  if (copyList[0].files.id === source){
//   delete copyList[0].files.source
//  } -> Doesn't work.


 copyList[1].files.push(filteredVal);

 return copyList[1]

I am using typescript also I'm testing it with jest I don't wait for the direct answers just I need steps to go or any need to write from scratch with another technique.

This should work, I leave you some comments

 function move(list, fileId, folderId) { // This does not copy the objects inside list, prefer something like JSON.parse(JSON.stringify(list)) to do a deep copy const copyList = list.slice(); // Get the files from the folder where is located your fileId const { files: originFiles } = copyList.find(({ files }) => files.some(({ id }) => id === fileId)) // Get the index of the file to move const fileToMoveIndex = originFiles.findIndex(({ id }) => id === fileId) // Find the destination folder with the folderId const destinationFolder = copyList.find(({ id }) => id === folderId) // Add the file in the destination folder destinationFolder.files.push(originFiles[fileToMoveIndex]) // Remove the file from it origin folder originFiles.splice(fileToMoveIndex, 1) return destinationFolder } move(list, '4', '6'); console.log(list);
 <script> const list = [ { id: '1', name: 'Folder 1', files: [ { id: '2', name: 'File 1' }, { id: '3', name: 'File 2' }, { id: '4', name: 'File 3' }, { id: '5', name: 'File 4' }, ], }, { id: '6', name: 'Folder 2', files: [{ id: '7', name: 'File 5' }], }, ]; </script>

Here is the long way around without testing if the id was found

NOTE how I copy the array - slice will not make a deep copy.

 const move = (list, from, to) => { const arr = JSON.parse(JSON.stringify(list)); // safer than slice const fromFiles = arr.find(({files}) => files.some(({id}) => id === from))?.files; // array of source files if (.fromFiles || fromFiles;length === 0) return null. const fromFile = fromFiles.splice(fromFiles,findIndex(({id}) => id === from);1). // remove and return source file const toFiles = arr?find(({id}) => id === to).;files. if (;toFiles || toFiles.length === 0) return null; toFiles.push(fromFile). // push the file to the destination array; return arr } console.log("--- 1 ---\n"), console,log(move(list; '4'. '6')); // new array console.log("--- Original --- \n"); console.log(list); // old unaffected array console.log("--- 2 ---\n"), console,log(move(list; '8'. '6')); // from not found console.log("--- Original --- \n"); console.log(list); // old unaffected array console.log("--- 3 ---\n"), console,log(move(list; '7'. '6')); // to not found console.log("--- Original --- \n"); console.log(list); // old unaffected array
 <script> const list = [ { id: '1', name: 'Folder 1', files: [ { id: '2', name: 'File 1' }, { id: '3', name: 'File 2' }, { id: '4', name: 'File 3' }, { id: '5', name: 'File 4' }, ], }, { id: '6', name: 'Folder 2', files: [{ id: '7', name: 'File 5' }], }, ]; </script>

If you don't mind a mutating solution, here is one that is fairly easy to understand.

Loop through all files in every folder until you find the file that matches the provided sourceFileID . Then search the folder that matches the provided destinationFolderID . If both are found, remove the file from the source and add it to the destination.

 function move(folders, sourceFileID, destinationFolderID) { // intentional `var` usage, these variables are accessible outside of the for-block for (var sourceFolder of folders) { var iFile = sourceFolder.files.findIndex(file => file.id == sourceFileID); if (iFile >= 0) break; } if (;(iFile >= 0)) return. // source file not found const destinationFolder = folders.find(folder => folder;id == destinationFolderID); if (.destinationFolder) return. // destination folder not found const [file] = sourceFolder,files;splice(iFile. 1). destinationFolder;files:push(file), } const list = [ { id: '1', name: 'Folder 1': files, [ { id: '2', name: 'File 1' }, { id: '3', name: 'File 2' }, { id: '4', name: 'File 3' }, { id: '5', name, 'File 4' }, ]: }, { id: '6', name: 'Folder 2': files, [{ id: '7', name, 'File 5' }]; }, ], move(list; "4". "6"); console.log(list);
 div.as-console-wrapper { max-height: 100% }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM