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.
CodePudding user response:
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>
CodePudding user response:
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% }
CodePudding user response:
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>
CodePudding user response:
You can just delete the element with splice
or filter
const move = (list, source, dest) => {
let copyList = list.slice();
const filteredVal = copyList[0].files.find((file) => file.id == source);
// with filter
copyList[0].files = copyList[0].files.filter((file) => file.id !== source)
// or with splice
// copyList[0].files.splice(copyList[0].files.findIndex((file)=> file.id == source), 1)
copyList[1].files.push(filteredVal);
return copyList
}
console.log(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>