2016-10-03 118 views
0

我有一個嵌套對象數組。這些對象採取以下兩種形式之一:通過索引從嵌套數組中刪除項目(遞歸)

// type a 
{ 
    value: 'some value' 
} 

// type b 
{ 
    array: [ 
     object of type a or b, 
     object of type a or b, 
     ... 
    ] 
} 

所以,基本陣列可以無限嵌套。鑑於一系列指數(我一直稱它爲「樹」),我怎樣才能在任意深度刪除單個項目?

什麼我到目前爲止的例子:

const baseArray = [ 
    { value: 'some value' }, 
    { array: [ 
      { value: 'some value' }, 
      { array: [ 
        { value: 'some value' }, 
        { value: 'some value' }, 
       ], 
      }, 
      { value: 'some value' }, 
      { array: [ 
        { value: 'some value' }, 
        { array: [ 
          { value: 'delete me' }, 
          { value: 'some value' }, 
         ] 
        }, 
       ], 
      }, 
     ], 
    } 
] 

const tree = [1, 3, 1, 0] 

function deleteNested(tree, inputArray) { 
    const index = tree.shift(); 
    console.log(inputArray, index); 
    const child = inputArray[index].array; 
    if (tree.length > 0) { 
     console.log(child) 
     return deleteNested(tree, child); 
    } 
    return [ 
     ...inputArray.slice(0, index), 
     ...inputArray.slice(index + 1) 
    ] 
} 
const originalArray = baseArray.slice(0); 
console.log(deleteNested(tree, baseArray), originalArray); 

我要刪除標記的對象給予它的「樹」的位置:[1, 3, 1, 0]

  • 第一,看在1(指數1,而不是0)的初始陣列的值,
  • 則3值,
  • 再看看1個值,
  • 然後最後刪除0值。

我上面有什麼不起作用,但讓我開始了。

函數需要遞歸才能在任何深度工作。理想情況下,不應該使用splice()來避免修改傳入它的數組,而應該返回一個新數組。

+0

我猜遞歸一個,而不是一段時間,因爲你已經知道提前迭代次數循環會更合適。 – Redu

回答

1

正如我在評論中所說,如果您事先知道迭代次數,則不應使用遞歸方法。 while循環是理想的,例如;

function delNestedItem(a,dm){ 
 
    var i = 0; 
 
    while (i < dm.length-1) a = a[dm[i++]].array; 
 
    a.splice(dm[i],1); 
 
} 
 

 
var data = [ 
 
    { value: 'some value' }, 
 
    { array: [ 
 
      { value: 'some value' }, 
 
      { array: [ 
 
        { value: 'some value' }, 
 
        { value: 'some value' }, 
 
       ], 
 
      }, 
 
      { value: 'some value' }, 
 
      { array: [ 
 
        { value: 'some value' }, 
 
        { array: [ 
 
          { value: 'delete me' }, 
 
          { value: 'some value' }, 
 
         ] 
 
        }, 
 
       ], 
 
      }, 
 
     ], 
 
    } 
 
      ], 
 

 
delMark = [1, 3, 1, 0]; 
 
delNestedItem(data,delMark); 
 
console.log(JSON.stringify(data,null,2));

0

這裏是你如何能做到在1減少:

const baseArray = [{ 
 
    value: 'some value' 
 
}, { 
 
    array: [{ 
 
    value: 'some value' 
 
    }, { 
 
    array: [{ 
 
     value: 'some value' 
 
    }, { 
 
     value: 'some value' 
 
    }, ], 
 
    }, { 
 
    value: 'some value' 
 
    }, { 
 
    array: [{ 
 
     value: 'some value' 
 
    }, { 
 
     array: [{ 
 
     value: 'delete me' 
 
     }, { 
 
     value: 'some value' 
 
     }, ] 
 
    }, ], 
 
    }, ], 
 
}]; 
 

 
const tree = [1, 3, 1, 0]; 
 

 

 
var deleted = tree.reduce(function(pos, pathIndex, index, arr) { 
 
    if (index + 1 < arr.length) { 
 
    return pos.array 
 
     ? pos.array[pathIndex] 
 
     : pos[pathIndex]; 
 
    } else { 
 
    pos.array = pos.array 
 
      .slice(0, pathIndex) 
 
      .concat(pos.array.slice(pathIndex + 1)); 
 
    return pos; 
 
    } 
 

 
}, baseArray); 
 
      
 
      console.log(baseArray); 
 
     

0

您可以生成一個新的數組出給定數組的只與未刪除的部分。

function ff(array, tree) { 
 
    function iter(array, level) { 
 
     var r = []; 
 
     array.forEach(function (a, i) { 
 
      if (tree[level] !== i) { 
 
       return r.push(a); 
 
      } 
 
      if (level + 1 !== tree.length && a.array) { 
 
       r.push({ array: iter(a.array, level + 1) }); 
 
      } 
 
     }); 
 
     return r; 
 
    } 
 
    return iter(array, 0); 
 
} 
 

 
var baseArray = [{ value: 'some value' }, { array: [{ value: 'some value' }, { array: [{ value: 'some value' }, { value: 'some value' }, ], }, { value: 'some value' }, { array: [{ value: 'some value' }, { array: [{ value: 'delete me' }, { value: 'some value' }, ] }, ], }, ], }], 
 
    tree = [1, 3, 1, 0], 
 
    copy = ff(baseArray, tree); 
 

 
console.log(copy); 
 
console.log(baseArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }