I am working on Laravel + Vue and I've been stuck in the process of finding the least node in a tree..
This image you will see below is the structure. In one node there must be 3 sub-nodes if he got a 4th one, he, the new node will fill-in in the least sub-nodes below
IMAGE HERE
I already implemented for the level 3 part but I am struggling on what should I do if ever the new node will fill-in in the least sub-nodes of level 4 nodes and level 5 up to level 7?
Anyone can share their knowledge to work make this work?
here's what I got so far
getMemberHasLowestMember(data) {
// get the lowest number of members count
let lowest_number_of_members = data.reduce((min, b) => Math.min(min, b.members.length), data[0].members.length)
// get the members who have the lowest number of members
let member_has_low_members = data.filter(member => member.members.length == lowest_number_of_members)
if(member_has_low_members.length > 1) {
// get the random number from length of members_has_low_members
let random_number = Math.floor(Math.random() * Math.floor(member_has_low_members.length))
return member_has_low_members[random_number]
} else {
return member_has_low_members[0]
}
},
In this case, I have 1 user data and it has teams object and in that object it has members but as the object go deeper, I still don't know how to get team member's own members until level 7
Related
I'm making a command that when executed by an admin, the bot will list all of the channels in a specific category with the CORRECT order as we see them on discord. Whenever I ask for <Category>.children.map(c => c.name) I always get unordered elements with voice channels in the top of the array and same for stage channels. What I need is a function (here sortChannels)having the array (or the Collection of channels in the category) correctly ordered exactly like we see them on Discord. Here's my category :
And i have :
function sortChannels(channels){
// What I need to figure out
}
let category = await guild.channels.fetch("935933604261592665")
let list = category.children
.sort(sortChannels)
.map(c => c.name)
.join('\n')
message.channel.send(list)
I tried using position
but it gives me the following result for each channel :
Which doesn't help alot, what i'm looking for is 1, 2, 3, 4, 5 etc..
You're looking for the channel's position. GuildChannels have a position and rawPosition property. Although I don't know which represents the appeared position, try both.
function sortChannels((a, b)){
return a.position - b.position;
// Or
return a.rawPosition - b.rawPosition;
}
GuildChannel#position
I have a representation of a process trough something that is very much like a DAG (Directed Acyclic Graph). This graph is represented with an adjacency table, but not like a "regular" adjacency table, there are few differences:
Each entry in the table is a list of lists,
Each "inner" list states the predecessor nodes required.
The idea for this data structure is to hold requirements of steps within a process. So, for example:
P = {1:[[]], 2:[[1]], 3:[[2]], 4:[[3]], 5:[[2]], 6:[[]], 7: [[4,6],[8,5]], 8:[[]]}
For process P, step 1 doesn't require any predecessor, step requires step 1,..., step 6 also doesn't require any predecessor, step 7 requires steps (4 and 6) OR (8 and 5).
Each step has a state (some ID reference) that determines if the next step can be executed or not, or if the process can be terminated or not.
In the example above, I would not be able to execute step 2 if step 1 didn't fulfill some specific condition regarding the state the same for step 5, which requires step 2 with state=something specific. And for step 7, the only way to execute it, would be if step 4&6 OR 5&8 have their corresponding state=something specific.
What I need is a way to get all the unique paths that lead to a certain step, so later I can check against this paths if the conditions are met. For step 7 it would be :
paths = [[1,2,3,4,6],[1,2,5,8]]
I've checked:
Python get all paths from graph
How to implement the search for all paths inside a directed graph in JavaScript? (reversing this??)
Depth first search list paths to all end nodes
How to find the nodes that leads to node A without traversing all the graph (directed graph)
Most of the information around points to some sort of modified DFS or some kind of enhanced Dijkstra. For what I've checked and tested none of the above gives me what I need which is a list of all "unique paths" that lead to a node that may be reached from "different paths".
The question is not language specific, so any example in any language would be appreciated :)
EDIT: 04/01/22
Further clarifications:
The steps are one way, meaning that node 1 is connected to step 2 by a distance of 1, to step 3 a distance of 2, and so on. But step/node 1 is not conntected with 6 or 8.
All graphs have a unique starting point and ending point. In the example 1 and 7.
Yes, node 5 should be connected to node 7. Img updated.
The number of nodes will always be <100.
How big is your graph? What is your performance requirement?
For a small graph like your example, Dijsktra is almost instant. So you do not need to store all the paths.
Set cost of all links to 1
Set cost of links that lead to nodes that are NOT in the required state to 10^10
Run Dijkstra to find shortest path from source to destination through nodes in required state.
I think I've managed to get what I needed, nevertheless I think the answer is overly complex.
Function to populate a tracker object with all the possible paths.
const tracker = {};
function getPaths (step, branchRef) {
const currentStepRequires = getStepRequires(step); // func that gets the array of arrays of current step
const oldBranchRef = branchRef;
const hasBranches = currentStepRequires.length > 1;
for (const branch of currentStepRequires) {
if (branch.length === 0) {
return;
}
if (!hasBranches && !branchRef) {
tracker[branch] = [];
}
if (!branchRef) branchRef = branch;
if (hasBranches) {
if (oldBranchRef && oldBranchRef !== branchRef) {
tracker[branch] = [...tracker[oldBranchRef]];
}
else if (tracker[branchRef]) {
tracker[branch] = [...tracker[branchRef]];
branchRef = branch;
}
else {
tracker[branch] = [];
}
}
for (const step of branch) {
tracker[branchRef].push(step);
getPaths(step, branchRef);
}
if (hasBranches) branchRef = '';
}
}
After the tracker object has been populated I need to remove the paths that are contained within the other paths.
I'm using lodash here to simplify the filtering, checking and adding the paths
const paths = [];
_.forEach(_.sortBy(tracker, path => path.length * -1), branch => {
const isSubpath = _.some(paths, path => _.isEqual(branch, _.intersection(path, branch)));
if (!isSubpath) {
paths.push(branch);
}
});
For the example above, this returns the following:
[[4,3,2,1,6], [8,5,2,1]]
I've also tested with more "branching", like example:
P = {1:[[]], 2:[[1]], 3:[[2]], 4:[[3]], 5:[[2]], 6:[[]], 7: [[4,6],[8],[5]], 8:[[6],[3]]}
Which returns:
[[4,3,2,1,6],[8,6],[8,3,2,1],[5,2,1]]
For now its working, but....as I said, I think its more complicated than it needs to be. So, any improvements are welcome.
I use firebase admin and realtime database on node.js
Data look like
When I want to get data where batch = batch-7, I was doing
let batch = "batch-7";
let ref = admin.database().ref('qr/');
ref.orderByChild("batch").equalTo(batch).on('value', (snapshot) =>
{
res.json(Object.assign({}, snapshot.val()));
ref.off();
});
All was OK!
But now i should create pagination, i.e. I should receive data on 10 elements depending on the page.
I use this code:
let page = req.query.page;// num page
let batch = req.params.batch;// batch name
let ref = admin.database().ref('qr/');
ref.orderByChild("batch").startAt(+page*10).limitToFirst(10).equalTo(batch)
.on('value', (snapshot) =>
{
res.json(Object.assign({}, snapshot.val()));
ref.off();
});
But I have error:
Query.equalTo: Starting point was already set (by another call to startAt or equalTo)
How do I get data in the amount of N, starting at position M, where batch equal my batch
You can only call one startAt (and/or endAt) OR equalTo. Calling both is not possible, nor does it make a lot of sense.
You seem to have a general misunderstanding of how startAt works though, as you're passing in an offset. Firebase queries are not offset based, but work purely on the value, often also referred to as an anchor node.
So when you want to get the data for a second page, and you order by batch, you need to pass in the value of batch for the anchor node; first item that you want to be returned. This anchor node is typically the last item of the previous page, since you don't know the first item of the next page yet. And for this anchor node, you need to know the value of the item you order on (batch) and usually also its key (if/when there may be multiple nodes with the same value for batch).
It also means that you usually request one item more than you need, which is the anchor node.
So when you request the first page, you should track the key/batch of the last node:
var lastKey, lastValue;
ref.orderByChild("batch").equalTo(batch).limitToFirst(10).on('value', (snapshot) => {
snapshot.forEach((child) => {
lastKey = child.key;
lastValue = child.child('batch').value();
})
})
Then when you need the second page, you do a query like that:
ref.orderByChild("batch").start(lastValue, lastKey).endAt(lastValue+"\uf8ff").limitToFirst(11).on('value', (snapshot) => {
snapshot.forEach((child) => {
lastKey = child.key;
lastValue = child.child('batch').value();
})
})
There's one more trick above here: I use startAt instead of equalTo, so that we can get pagination working. But it then uses endAt to ensure we still end at the correct item, by using the last known Unicode character as the last batch value to return.
I'd also highly recommend checking out some of the previous questions on pagination with the Firebase Realtime Database.
I has to display a list of books that containes more than 50 000 book.
I want to display paged list where for each page i invoke a method that gives me 20 books.
List< Books > Ebooks = Books.GetLibrary(index);
But using PagedList doesnt match with my want because it creates a subset of the collection of objects given and accesse to each subset with the index. And refering to the definition of its methode, i had to charge the hole list from the begining.
I also followed this article
var EBooks = from b in db.Books select b;
int pageSize = 20;
int pageNumber = (page ?? 1);
return View(Ebooks.ToPagedList(pageNumber, pageSize));
But doing so, i has to invoke (var Books = from b in db.Books select b; ) on each index
**EDIT****
I'm searching for indications to achieve this
List< Books > Ebooks = Books.GetLibrary(index);
and of course i has the number of all the books so i know the number of pages
So i'm searching for indication that leads me to achieve it: for each index, i invoke GetLibrary(index)
any suggestions ?
Have you tried something like:
var pagedBooks = Books.GetLibrary().Skip(pageNumber * pageSize).Take(pageSize);
This assumes a 0-based pageNumber.
If that doesn't work, can you add a new method to the Books class that gets a paged set directly from the data source?
Something like "Books.GetPage(pageNumber, pageSize);" that way you don't get the entire collection every time.
Other than that, you may have to find a way to cache the initial result of Books.GetLibrary() somewhere.
I have a 1:N relationship between Account and Portfolios in Dynamics CRM
I.e each account has multiple Portfolios and Each Portfolio has Specific Assets.
I am trying to create a field on Account Form which calculates the sum of "ALL Assets of All related portfolios" of the account and display it on the Account form
As a workaround,I tried to create a Portfolio view grouping by Account but it doesnt SUM and rollup the Portfolio assets to Account level.
So on account Form i am trying to create a textfield which calculates the Total Account Assets to be $25,000 in this example
function setupGridRefresh() {
var targetgrid = document.getElementById("NAME OF SUBGRID");
// If already loaded
if (targetgrid.readyState == 'complete') {
targetgrid.attachEvent("onrefresh", subGridOnload);
}
else {
targetgrid.onreadystatechange = function applyRefreshEvent() {
var targetgrid = document.getElementById("NAME OF SUBGRID");
if (targetgrid.readyState == 'complete') {
targetgrid.attachEvent("onrefresh", subGridOnload);
}
}
}
subGridOnload();
}
function subGridOnload() {
//debugger;
var grid = Xrm.Page.ui.controls.get('NAME OF SUBGRID')._control;
var sum = 0.00;
if (grid.get_innerControl() == null) {
setTimeout(subGridOnload, 1000);
return;
}
else if (grid.get_innerControl()._element.innerText.search("Loading") != -1) {
setTimeout(subGridOnload, 1000);
return;
}
var ids = grid.get_innerControl().get_allRecordIds();
var cellValue;
for (i = 0; i < ids.length; i++) {
if (grid.get_innerControl().getCellValue('FIELD NAME LOWER CASE', ids[i]) != "") {
cellValue = grid.get_innerControl().getCellValue('FIELD NAME LOWER CASE', ids[i]);
cellValue = cellValue.substring(2);
cellValue = parseFloat(cellValue);
sum = sum + cellValue;
}
}
var currentSum = Xrm.Page.getAttribute('DESTINATION FIELD').getValue();
if (sum > 0 || (currentSum != sum && currentSum != null)) {
Xrm.Page.getAttribute('DESTINATION FIELD').setValue(sum);
}
}
I pieced this together from a couple of sources and currently use it one of my solutions. Let me know if you need some more help or if I've misread the question. (Btw, this solution is based on the assumption that you need the total to change when the subgrid has entries added or removed. If this is not the requirement, I would suggest the RetrieveMultiple OData call.)
Take a look at AutoSummary from Gap Consulting, well worth the cost. Or spend time to build your own. You need a field on the Account record which is updated every time you:
create a Portfolio record
update the value in a Portfolio record
delete a Portfolio record
re-parent a Partfolio record from one Account to another
The first two are easy enough to do with workflow or javascript on the onSave event on the portfolio. Third can only be done by workflow, not javascript (I think). Last one would need onLoad javascript to store current value of Account lookup so that onSave can compare and then decrement one and increment the other. All four could be done with a plugin.
Although this has been answered already, I'll put a second option on the plate for you. Take a look at FormulaManager from North 52 as well. You get a certain amount of Formulas for free so it might be an even more cost effective solution.
Update
To add to this, if the field is solely for reporting a value (and doesn't need to be saved to the database) then rather than using a physical field and plugins you could build a Web Resource that executes an Aggregated FetchXml query and simply displays the resulting value.
Again, this is something that I know Formula Manager does out of the box. Have never used Auto Summary.