2
\$\begingroup\$

I have the following function, which I believe could be improved with .

 function findSelectedInList(list){
 for(var i=0;i<=list.length;i++){ 
 var currentItem = list[i];
 if(currentItem.selected === "selected"){
 return currentItem; 
 } 
 var selectedNode = findSelectedInList(currentItem.children)
 if(selectedNode){
 return selectedNode;
 } 
 }
 return void 0;
 }

Here are some sample inputs:

 var treeList = [ { "roleName": "User", 
 "roleId": "role1", 
 "children": [ { "roleName": "subUser1", "roleId": "role11", "children": [], "selected": "selected" }]
 }];
 var treeList2 = [ { "roleName": "User", "roleId": "role1", "children": [],"selected":"selected"}];
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Nov 8, 2017 at 12:31
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Something like return (currentItem.selected === "selected") || findSelectedInList(currentItem.children) would have fewer variables and "look" more recursive. \$\endgroup\$ Commented Nov 8, 2017 at 13:48
  • \$\begingroup\$ Can only one item in the tree have selected set? If not, may any item with selected set be returned? \$\endgroup\$ Commented Nov 8, 2017 at 23:55
  • \$\begingroup\$ @Gerrit0 only one item can be selected. I am writing a utility class for this github.com/eu81273/angular.treeview \$\endgroup\$ Commented Nov 9, 2017 at 3:57

1 Answer 1

3
\$\begingroup\$

Initially, I considered suggesting using Array.filter() but then that wouldn't allow breaking out of the loop once a selected item was found.

One approach is to use Array.some() or Array.find() (and disregard the return value) with a ternary operator. A variable can be initialized as the first line, then the .some() callback returns the result of setting that variable to either the current item if it is selected, otherwise the return value of the recursive call.

function findSelectedInList(list) {
 var selected;
 list.some(function(currentItem) {
 return selected = currentItem.selected === "selected" ? currentItem : findSelectedInList(currentItem.children);
 });
 return selected;
}

And one could use features like arrow functions and the let keyword), to condense it slightly:

function findSelectedInList(list){
 let selected;
 list.some((currentItem) => selected = currentItem.selected === "selected" ? currentItem : findSelectedInList(currentItem.children));
 return selected;
}

To see this demonstrated, expand the snippet below.

var treeList = [{
 "roleName": "User",
 "roleId": "role1",
 "children": [{
 "roleName": "subUser1",
 "roleId": "role11",
 "children": [],
 "selected": "selected"
 }]
}];
var treeList2 = [{
 "roleName": "User",
 "roleId": "role1",
 "children": [],
 "selected": "selected"
}];
var treeList3 = [{
 "roleName": "User",
 "roleId": "role1",
 "children": []
}];
function findSelectedInList(list) {
 var selected;
 list.some(function(currentItem) {
 return selected = currentItem.selected === "selected" ? currentItem : findSelectedInList(currentItem.children);
 });
 return selected;
}
console.log('treeList: ', findSelectedInList(treeList));
console.log('treeList2: ', findSelectedInList(treeList2));
console.log('treeList3: ', findSelectedInList(treeList3));

I know it doesn't really cover the find or some methods, but these functional JS exercises are a good thing to go through.

answered Nov 9, 2017 at 17:43
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.