Usuwanie z obiektu przy użyciu JavaScript

głosy
17

Mam obiektu, jak pokazano na rysunku:

const arr = [
  {
    name: 'FolderA',
    child: [
      {
        name: 'FolderB',
        child: [
          {
            name: 'FolderC0',
            child: [],
          },
          {
            name: 'FolderC1',
            child: [],
          },
        ],
      },
    ],
  },
  {
    name: 'FolderM',
    child: [],
  },
];

I mam ścieżkę jako ciąg znaków:

var path = 0-0-1.

Muszę usunąć obiekt:

{
    name: 'FolderC1',
    child: [],
 },

Które mogę zrobić, wykonując,

arr[0].child[0].splice(1, 1);

Ale chcę, aby to zrobić dynamicznie. Ponieważ ciąg ścieżka może być cokolwiek, chcę wyżej „” operator i definicja splice być tworzone dynamicznie splatać w konkretnym miejscu.

Utwórz 18/12/2018 o 11:13
źródło użytkownik
W innych językach...                            


5 odpowiedzi

głosy
4

Można podzielić pathi używać części, tak jak poniżej:

let path = '0-0-1';
let parts = path.split('-');

// Call your splice using your parts (unsure if your '1' is the index, or deleteCount).

// If parts[2] is the index
arr[parts[0]].child[parts[1]].splice(parts[2], 1);

// If parts[2] is the deleteCount:
arr[parts[0]].child[parts[1]].splice(1, parts[2]);
Odpowiedział 18/12/2018 o 11:18
źródło użytkownik

głosy
17

Można zmniejszyć indeksy zapisując ostatni indeks i powrocie dzieci rzeczywistego wskaźnika. Później splice z ostatniego indeksu.

function deepSplice(array, path) {
    var indices = path.split('-'),
        last = indices.pop();

    indices
        .reduce((a, i) => a[i].child, array)
        .splice(last, 1);
}

const array = [{ name: 'FolderA', child: [{ name: 'FolderB', child: [{ name: 'FolderC0', child: [] }, { name: 'FolderC1', child: [] }] }] }, { name: 'FolderM', child: [] }];

deepSplice(array, "0-0-1");
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Odpowiedział 18/12/2018 o 11:19
źródło użytkownik

głosy
0

Jeśli ścieżka jest zawsze będzie się składać przez 3 (lub mniej) indeksów można to zrobić łatwo jak następuje:

function deleteByPath(arr, path) {
   const index = path.split('-').map((x) => +x);
   if ( index.length < 1) {
      return null;
   } else if ( 1 === index.length ) {
     return arr.splice(index[0], 1);
   } else if ( 2 === index.length ) {
     return arr[index[0]].child.splice(index[1], 1);
   } else {
     return arr[index[0]].child[index[1]].child.splice(index[2], 1);
   }
}

const arr = [
  {
    name: 'FolderA',
    child: [
      {
        name: 'FolderB',
        child: [
          {
            name: 'FolderC0',
            child: [],
          },
          {
            name: 'FolderC1',
            child: [],
          },
        ],
      },
    ],
  },
  {
    name: 'FolderM',
    child: [],
  },
];

console.log(deleteByPath(arr, "0-0-1"));
console.log(deleteByPath(arr, "0-1"));
console.log(deleteByPath(arr, "0"));

Jeśli ścieżka będzie składać się z mniej niż 3 może części można dostosować funkcję deleteByPathdo obsługi spraw na podstawie liczby części.

Jeśli ścieżka będzie arbitralny i może mieć dowolną długość można regulować deleteByPathfunkcję być rekurencyjne jak następuje:

function deleteByIndexRecursive(arr, index, current) {
  return current+1 < index.length ? deleteByIndexRecursive(arr.child[index[current]], current+1) : arr.child.splice(index[current], 1); 
}
function deleteByPath(arr, path) {
   const index = path.split('-').map((x) => +x);
   if ( 1>index.length) {
     return null;
   } else if ( 1===index.length) {
     return arr.splice(index[0], 1);
   } else {
     return deleteByIndexRecursive(arr[index[0]], index, 1);
   }
}
Odpowiedział 18/12/2018 o 11:22
źródło użytkownik

głosy
2

Można napisać rekurencyjną funkcję, która porusza się w dół hierarchii aż ścieżka jest dostępna. Poniżej znajduje się bardzo minimalny fragment.

const arr = [
  {
    name: 'FolderA',
    child: [
      {
        name: 'FolderB',
        child: [
          {
            name: 'FolderC0',
            child: [],
          },
          {
            name: 'FolderC1',
            child: [],
          },
        ],
      },
    ],
  },
  {
    name: 'FolderM',
    child: [],
  },
];

let ar_path = "0-0-1";

function deleteRecursive(arr, path) {
  if(Array.isArray(arr) && path.length > 0){
     const index = Number(path.shift());
     if (path.length > 0) 
        deleteRecursive(arr[index].child, path)
     else 
        arr.slice(index, 1);
  } else {
     console.log('invalid');
  }
}


deleteRecursive(arr, ar_path.split('-'))

console.log(arr);

Odpowiedział 18/12/2018 o 11:25
źródło użytkownik

głosy
0

//Variable setup:
const arr = [
    {
        name: 'FolderA',
        child: [
            {
                name: 'FolderB',
                child: [
                    {
                        name: 'FolderC0',
                        child: [],
                    },
                    {
                        name: 'FolderC1',
                        child: [],
                    },
                ],
            },
        ],
    },
    {
        name: 'FolderM',
        child: [],
    },
];
const path = "0-0-1";
//Break the path into pieces to iterate through:
const pathArray = path.split("-");
//Javascript assignments are by reference, so arrayToManage is going to be an internal piece within the original array
let arrayToManage = arr;
//We are going to iterate through the children of the array till we get above where we want to remove
while(pathArray.length > 1){
    const key = parseInt(pathArray.shift());
    arrayToManage = arrayToManage[key].child;
}
//Get the last position of the last array, where we want to remove the item
const key = parseInt(pathArray.shift());
arrayToManage.splice(key,1);
//And because it's all by reference, changed we made to arrayToManage were actually made on the arr object
console.log("end result:", JSON.stringify(arr));

Odpowiedział 18/12/2018 o 12:04
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more