[英]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" ]
如果您不喜歡reduce
,可能使用filter
和map
。
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();
}
這是一個使用遞歸的相當冗長的,
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;
}
你可以嘗試這樣的事情:
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.