簡體   English   中英

獲取父元素及其所有子元素的數組

[英]get array of parent and all of its child

假設我有這種數據......

data = [{
    "_id" : "1",
    "parentId" : "thisPostId",
    "topLevelId" : "1",
    "text" : "<p>comment</p>",
},
{
    "_id" : "2",
    "parentId" : "1",
    "topLevelId" : "1",
    "text" : "<p>reply to comment</p>",
},
{
    "_id" : "3",
    "parentId" : "2",
    "topLevelId" : "1",
    "text" : "<p>reply to reply to comment</p>",
},
{
    "_id" : "4",
    "parentId" : "3",
    "topLevelId" : "1",
    "text" : "<p>reply to reply to reply to comment</p>",
}]

我需要刪除評論及其所有孩子......

如果要刪除的注釋是_id:1 ,,那么我需要一個["1","2","3","4"]數組,然后我可以運行Coll.remove({_id:{$in:["1","2","3","4"]}}, callback);

如果要刪除的注釋是_id:2 ,,那么我需要一個["2","3","4"]數組["2","3","4"]

如果要刪除的注釋是_id:3 ,,那么我需要一個["3","4"]的數組

如果要刪除的注釋是_id:4 ,,那么我需要一個["4"]的數組

我試過這個(不知道)......

_.forEach(data, function(value, key){
    _.pluck(_.where(key, { "parentId" : "2" }), '_id');
});

並沒有工作......

任何有關javascript / lodash / underscore的幫助將不勝感激,,,

謝謝...

下面是使用本機Array.prototype.reduce方法的另一種解釋,只將子元素添加到返回的數組中。

編輯,沒有正確讀取問題,現在將返回當前的id和所有孩子。

 var data = [{ "_id" : "1", "parentId" : "thisPostId", "topLevelId" : "1", "text" : "<p>comment</p>", }, { "_id" : "2", "parentId" : "1", "topLevelId" : "1", "text" : "<p>reply to comment</p>", }, { "_id" : "3", "parentId" : "2", "topLevelId" : "1", "text" : "<p>reply to reply to comment</p>", }, { "_id" : "4", "parentId" : "3", "topLevelId" : "1", "text" : "<p>reply to reply to reply to comment</p>", }]; function getChildIds( arr, id ){ var parentFound = false; return arr.reduce(function( ret, item ){ if( parentFound === false && item._id == id ){ parentFound = true; } if( parentFound ) { ret = ret.concat( item._id ); } return ret; }, []); } console.log( getChildIds(data, '1') ); console.log( getChildIds(data, '2') ); console.log( getChildIds(data, '3') ); console.log( getChildIds(data, '4') ); 
 <script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script> 

任何訂單,不知道為什么有必要考慮。

 var data = [{ "_id": "2", "parentId": "1", "topLevelId": "1", "text": "<p>reply to comment</p>", }, { "_id": "1", "parentId": "thisPostId", "topLevelId": "1", "text": "<p>comment</p>", }, { "_id": "4", "parentId": "3", "topLevelId": "1", "text": "<p>reply to reply to reply to comment</p>", }, { "_id": "3", "parentId": "2", "topLevelId": "1", "text": "<p>reply to reply to comment</p>", }]; function getChildIdsInAnyOrder(arr, id) { return arr.reduce(function(ret, item) { if ( parseInt(item._id) >= parseInt(id) ) { ret = ret.concat(item._id); } return ret; }, []); } console.log(getChildIdsInAnyOrder(data, '1')); console.log(getChildIdsInAnyOrder(data, '2')); console.log(getChildIdsInAnyOrder(data, '3')); console.log(getChildIdsInAnyOrder(data, '4')); 
 <script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script> 

首先,您需要一個函數來從對象獲取topLevelId ,並匹配搜索ID:

function getTLID(searchId) {
  return data.filter(function(el) {
    return el._id === searchId;
  })[0].topLevelId;
}

使用reduce :將每個對象的_id添加到具有該搜索ID的返回數組, 並且具有搜索ID 或者具有大於或等於搜索ID的parentId ,使用map來獲取_id s。

function getIdArray(searchId) {
  var tlid = getTLID(searchId);
  return data.reduce(function (p, c) {
    var matchSearchId = +c.parentId >= +searchId || c._id === searchId;
    if (c.topLevelId === tlid && matchSearchId) p.push(c._id);
    return p;
  }, []).sort();
}

getIdArray('1') // [ "1", "2", "3", "4" ]
getIdArray('2') // [ "2", "3", "4" ]
getIdArray('3') // [ "3", "4" ]
getIdArray('4') // [ "4" ]

DEMO

如果您不喜歡reduce ,可能使用filtermap

function getIdArray(searchId) {
  var tlid = getTLID(searchId);
  return data.filter(function(el) {
    var matchSearchId = +el.parentId >= +searchId || el._id === searchId;
    return el.topLevelId === tlid && matchSearchId;
  }).map(function(el) {
    return el._id;
  }).sort();
}

DEMO

這是一個使用遞歸的相當冗長的,

function getIDs(arr, id) {
arr = arr || data;
var ret = [];
for (var i = 0; i < arr.length; i++) {
    var item = arr[i];
    if (item.parentId == id || item._id == id) {
        if (ret.indexOf(item._id) < 0) {
            ret.push(item._id);
            var newret = []
            for (var x = 0; x < arr.length; x++) {
                if (x != i) newret.push(arr[x]);
            }
            var children = getIDs(newret, item._id);
            if (children.length > 0) {
                for (var j = 0; j < children.length; j++) {
                    if (!(ret.indexOf(children[j]) >= 0)) { ret.push(children[j]); }
                }
            }
        }

    }
}
return ret;

}

它的工作原理是獲取所需父級的id,然后獲取其子級的id及其子級的子級,它可以整天執行此操作...

首先,你需要獲得已提到_id的項的索引,如果array存在item,那么你可以使用array.splice從提到的索引中刪除n元素。 為了充分利用的項目deleted節點, deepcopy的陣列的存儲在temperory變量。

splice()方法通過刪除現有元素和/或添加新元素來更改數組的內容。

您可以使用data.length - index計算刪除計數

 var data = [{ "_id": "1", "parentId": "thisPostId", "topLevelId": "1", "text": "<p>comment</p>", }, { "_id": "2", "parentId": "1", "topLevelId": "1", "text": "<p>reply to comment</p>", }, { "_id": "3", "parentId": "2", "topLevelId": "1", "text": "<p>reply to reply to comment</p>", }, { "_id": "4", "parentId": "3", "topLevelId": "1", "text": "<p>reply to reply to reply to comment</p>", }]; var getIndex = function(_id) { for (var i = 0; i < data.length; i++) { if (data[i]._id == _id) { return i; } } }; function deepCopy(obj) { if (null == obj || "object" != typeof obj) return obj; var copy = obj.constructor(); for (var attr in obj) { if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr]; } return copy; } var _id = 1; var index = getIndex(_id); var _temp = deepCopy(data); var removedData = data.splice(index, 1); alert(removedData); if (typeof index !== 'undefined') { var neededData = _temp.splice(index, (_temp.length - index)); alert(neededData); } 

在這里小提琴

試試這個:

HTML:

<input type="text" id="Txt" />

<button type="button" onclick="check();">
Check
</button>

JS:

data = [{
    "_id" : "1",
    "parentId" : "thisPostId",
    "topLevelId" : "1",
    "text" : "<p>comment</p>",
},
{
    "_id" : "2",
    "parentId" : "1",
    "topLevelId" : "1",
    "text" : "<p>reply to comment</p>",
},
{
    "_id" : "3",
    "parentId" : "2",
    "topLevelId" : "1",
    "text" : "<p>reply to reply to comment</p>",
},
{
    "_id" : "4",
    "parentId" : "3",
    "topLevelId" : "1",
    "text" : "<p>reply to reply to reply to comment</p>",
}];


function check() {
    getIds(document.getElementById("Txt").value);
}

function getIds(id) {
    var allow = false,
        result = [];

    for (var i = 0; i < data.length; i++) {
        if (data[i]._id == id) {
            allow = true;
        }
        if (allow) {
            result.push(data[i]._id)
        }
    }

    retrun result;
}

你可以嘗試這樣的事情:

的jsfiddle

 var data = [{ "_id": "1", "parentId": "thisPostId", "topLevelId": "1", "text": "<p>comment</p>", }, { "_id": "2", "parentId": "1", "topLevelId": "1", "text": "<p>reply to comment</p>", }, { "_id": "3", "parentId": "2", "topLevelId": "1", "text": "<p>reply to reply to comment</p>", }, { "_id": "4", "parentId": "3", "topLevelId": "1", "text": "<p>reply to reply to reply to comment</p>", }]; function getDependentList(id) { var retList = []; data.forEach(function(item) { if (item.parentId == id) retList.push(item["_id"]); }); if (retList.length > 0) { retList.forEach(function(item) { retList = retList.concat(getDependentList(item).slice(0)); }); } return retList; } function getRemoveList() { var id = document.getElementById("txtInput").value; var removeList = []; removeList.push(id); removeList = removeList.concat(getDependentList(id)) console.log(removeList); } 
 <input type="text" id="txtInput"> <button onclick="getRemoveList()">get Lists</button> 

這是一個帶有臨時對象和id的遞歸調用的提議。

臨時對象o包含所有id及其子級

{
    "1": ["2"],
    "2": ["3"],
    "3": ["4"],
    "thisPostId": ["1"]
}

構建此對象后,將獲取查找的ID,並檢查該對象是否包含該屬性。 雖然所有peopertys都是數組,但可以遍歷go()並獲取所有id以進行收集。 如果有另一個子節點,則遞歸迭代正在進行。

 var data = [{ "_id": "1", "parentId": "thisPostId", "topLevelId": "1", "text": "<p>comment</p>", }, { "_id": "2", "parentId": "1", "topLevelId": "1", "text": "<p>reply to comment</p>", }, { "_id": "3", "parentId": "2", "topLevelId": "1", "text": "<p>reply to reply to comment</p>", }, { "_id": "4", "parentId": "3", "topLevelId": "1", "text": "<p>reply to reply to reply to comment</p>", }]; function getConnected(s) { function go(a) { r.push(a); o[a] && o[a].forEach(go); } var o = data.reduce(function (r, a) { r[a.parentId] = r[a.parentId] || []; r[a.parentId].push(a._id); return r; }, {}), r = [s]; o[s] && o[s].forEach(go); return r; } for (var i = 1; i <= 4; i++) { document.write('"' + i + '": ' + JSON.stringify(getConnected(i.toString())) + '<br>'); } 

在OP的評論中,你說你正在使用meteorjs而你似乎想要級聯刪除文檔。 Meteorjs鈎子可以輕松實現:

var idToRemove;
Coll.remove({ _id: idToRemove }, callback);

// what to do after removing a Coll document
Coll.after.remove(function (userId, doc) {
    Coll.remove({ parentId: doc._id });
});

您需要先安裝collection-hooks包。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM