kandi background
Explore Kits

javascript-algorithms | Algorithms and data structures | Learning library

 by   trekhleb JavaScript Version: Current License: MIT

 by   trekhleb JavaScript Version: Current License: MIT

Download this library from

kandi X-RAY | javascript-algorithms Summary

javascript-algorithms is a JavaScript library typically used in Tutorial, Learning, Example Codes applications. javascript-algorithms has no bugs, it has no vulnerabilities, it has a Permissive License and it has medium support. You can install using 'npm i javascript-algorithms-and-data-structures' or download it from GitHub, npm.
This repository contains JavaScript based examples of many popular algorithms and data structures. Each algorithm and data structure has its own separate README with related explanations and links for further reading (including ones to YouTube videos). Read this in other languages: 简体中文, 繁體中文, 한국어, 日本語, Polski, Français, Español, Português, Русский, Türk, Italiana, Bahasa Indonesia, Українська, Arabic, Deutsch.
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • javascript-algorithms has a medium active ecosystem.
  • It has 138596 star(s) with 22983 fork(s). There are 4269 watchers for this library.
  • It had no major release in the last 12 months.
  • There are 98 open issues and 185 have been closed. On average issues are closed in 32 days. There are 141 open pull requests and 0 closed requests.
  • It has a neutral sentiment in the developer community.
  • The latest version of javascript-algorithms is current.
This Library - Support
Best in #Learning
Average in #Learning
This Library - Support
Best in #Learning
Average in #Learning

quality kandi Quality

  • javascript-algorithms has 0 bugs and 0 code smells.
This Library - Quality
Best in #Learning
Average in #Learning
This Library - Quality
Best in #Learning
Average in #Learning

securitySecurity

  • javascript-algorithms has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • javascript-algorithms code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.
This Library - Security
Best in #Learning
Average in #Learning
This Library - Security
Best in #Learning
Average in #Learning

license License

  • javascript-algorithms is licensed under the MIT License. This license is Permissive.
  • Permissive licenses have the least restrictions, and you can use them in most projects.
This Library - License
Best in #Learning
Average in #Learning
This Library - License
Best in #Learning
Average in #Learning

buildReuse

  • javascript-algorithms releases are not available. You will need to build from source code and install.
  • Deployable package is available in npm.
  • Installation instructions are not available. Examples and code snippets are available.
This Library - Reuse
Best in #Learning
Average in #Learning
This Library - Reuse
Best in #Learning
Average in #Learning
Top functions reviewed by kandi - BETA

kandi has reviewed javascript-algorithms and discovered the below as its top functions. This is intended to give you an instant insight into javascript-algorithms implemented functionality, and help decide if they suit your requirements.

  • Convert a ZBox into a ZBox
    • Retrieves the number of consecutive columns in the board .
      • Extracts the edges of the given graph .
        • Sorts all vertices in the given graph
          • Add a new option to the current array .
            • This is the algorithm for searching for the triangulation into a cycle .
              • Makes a stack up to the root node .
                • Traverse the chessboard .
                  • Recursively compute the state of the puzzle .
                    • Find all the paths in the given start .

                      Get all kandi verified functions for this library.

                      Get all kandi verified functions for this library.

                      javascript-algorithms Key Features

                      📝 Algorithms and data structures implemented in JavaScript with explanations and links to further readings

                      How to use this repository

                      copy iconCopydownload iconDownload
                      npm install
                      

                      How to sort and chunk a dependency tree of actions, so you can batch as many actions as possible together at each step?

                      copy iconCopydownload iconDownload
                      from collections import defaultdict
                      
                      def ExtractGraph(cmds):
                        """Gets a dependency graph from verbose command input data."""
                        graph = defaultdict(set)
                        for cmd in cmds:
                          node = cmd['set']
                          graph[node].update(set())
                          inputs = cmd.get('input')
                          if inputs:
                            for _, val in inputs.items():
                              graph[node].add(val['path'][0])
                        return graph
                      
                      def FindSources(graph):
                        """Returns the nodes of the given graph having no dependencies."""
                        sources = set()
                        for node, edges in graph.items():
                          if not edges:
                            sources.add(node)
                        return sources
                      
                      def GetLevels(dependencies):
                        """Returns sequence levels satisfying given dependency graph."""
                        sources = FindSources(dependencies)
                        level = set(sources)
                        done = set(level)
                        todos = dependencies.keys() - done
                        levels = []
                        while level:
                          levels.append(level)
                          # Next level is jobs that have all dependencies done
                          new_level = set()
                          # A clever data structure could find the next level in O(k log n)
                          # for a level size of k and n jobs. This needs O(n).
                          for todo in todos:
                            if dependencies[todo].issubset(done):
                              new_level.add(todo)
                          todos.difference_update(new_level)
                          done.update(new_level)
                          level = new_level
                        return levels
                      
                      cmds = [
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key1' },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key2' },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key3' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key5' },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key6' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key7' },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key8' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key9' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key10', 'input' : {
                            'y' : { 'type' : 'binding', 'path' : ['key6', 'foo'] },
                            'z' : { 'type' : 'binding', 'path' : ['key1', 'bar'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key4', 'input' : {
                            'x' : { 'type' : 'binding', 'path' : ['key2', 'baz'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key11', 'input' : {
                            'a' : { 'type' : 'binding', 'path' : ['key10', 'z'] },
                            'b' : { 'type' : 'binding', 'path' : ['key1', 'bar'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key12', 'input' : {
                            'p' : { 'type' : 'binding', 'path' : ['key10', 'z'] },
                            'q' : { 'type' : 'binding', 'path' : ['key11', 'a'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key13' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key14' },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key15', 'input' : {
                            'a' : { 'type' : 'binding', 'path' : ['key8', 'z'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb5', 'set' : 'key16' },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key17' },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key18', 'input' : {
                            'm' : { 'type' : 'binding', 'path' : ['key4', 'x'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key19', 'input' : {
                            'm' : { 'type' : 'binding', 'path' : ['key4', 'x'] },
                            'n' : { 'type' : 'binding', 'path' : ['key13', 'a'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key20', 'input' : {
                            'm' : { 'type' : 'binding', 'path' : ['key18', 'm'] },
                            'n' : { 'type' : 'binding', 'path' : ['key17', 'm'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key21' },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key22', 'input' : {
                            'w' : { 'type' : 'binding', 'path' : ['key18', 'm'] },
                            'x' : { 'type' : 'binding', 'path' : ['key17', 'm'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key23' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key24' },
                      ]
                          
                      dependencies = ExtractGraph(cmds)
                      levels = GetLevels(dependencies)
                      print(levels)
                      
                      [
                      {'key9', 'key3', 'key24', 'key7', 'key17', 'key8', 'key21', 'key1',
                           'key5', 'key2', 'key16', 'key6', 'key23', 'key13', 'key14'}, 
                      {'key15', 'key4', 'key10'}, 
                      {'key19', 'key18', 'key11'}, 
                      {'key22', 'key12', 'key20'}
                      ]
                      
                      from collections import defaultdict
                      
                      def ExtractGraph(cmds):
                        """Gets a dependency graph from verbose command input data."""
                        graph = defaultdict(set)
                        for cmd in cmds:
                          node = cmd['set']
                          graph[node].update(set())
                          inputs = cmd.get('input')
                          if inputs:
                            for _, val in inputs.items():
                              graph[node].add(val['path'][0])
                        return graph
                      
                      def FindSources(graph):
                        """Returns the nodes of the given graph having no dependencies."""
                        sources = set()
                        for node, edges in graph.items():
                          if not edges:
                            sources.add(node)
                        return sources
                      
                      def GetLevels(dependencies):
                        """Returns sequence levels satisfying given dependency graph."""
                        sources = FindSources(dependencies)
                        level = set(sources)
                        done = set(level)
                        todos = dependencies.keys() - done
                        levels = []
                        while level:
                          levels.append(level)
                          # Next level is jobs that have all dependencies done
                          new_level = set()
                          # A clever data structure could find the next level in O(k log n)
                          # for a level size of k and n jobs. This needs O(n).
                          for todo in todos:
                            if dependencies[todo].issubset(done):
                              new_level.add(todo)
                          todos.difference_update(new_level)
                          done.update(new_level)
                          level = new_level
                        return levels
                      
                      cmds = [
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key1' },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key2' },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key3' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key5' },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key6' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key7' },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key8' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key9' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key10', 'input' : {
                            'y' : { 'type' : 'binding', 'path' : ['key6', 'foo'] },
                            'z' : { 'type' : 'binding', 'path' : ['key1', 'bar'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key4', 'input' : {
                            'x' : { 'type' : 'binding', 'path' : ['key2', 'baz'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key11', 'input' : {
                            'a' : { 'type' : 'binding', 'path' : ['key10', 'z'] },
                            'b' : { 'type' : 'binding', 'path' : ['key1', 'bar'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key12', 'input' : {
                            'p' : { 'type' : 'binding', 'path' : ['key10', 'z'] },
                            'q' : { 'type' : 'binding', 'path' : ['key11', 'a'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key13' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key14' },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key15', 'input' : {
                            'a' : { 'type' : 'binding', 'path' : ['key8', 'z'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb5', 'set' : 'key16' },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key17' },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key18', 'input' : {
                            'm' : { 'type' : 'binding', 'path' : ['key4', 'x'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key19', 'input' : {
                            'm' : { 'type' : 'binding', 'path' : ['key4', 'x'] },
                            'n' : { 'type' : 'binding', 'path' : ['key13', 'a'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key20', 'input' : {
                            'm' : { 'type' : 'binding', 'path' : ['key18', 'm'] },
                            'n' : { 'type' : 'binding', 'path' : ['key17', 'm'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key21' },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key22', 'input' : {
                            'w' : { 'type' : 'binding', 'path' : ['key18', 'm'] },
                            'x' : { 'type' : 'binding', 'path' : ['key17', 'm'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key23' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key24' },
                      ]
                          
                      dependencies = ExtractGraph(cmds)
                      levels = GetLevels(dependencies)
                      print(levels)
                      
                      [
                      {'key9', 'key3', 'key24', 'key7', 'key17', 'key8', 'key21', 'key1',
                           'key5', 'key2', 'key16', 'key6', 'key23', 'key13', 'key14'}, 
                      {'key15', 'key4', 'key10'}, 
                      {'key19', 'key18', 'key11'}, 
                      {'key22', 'key12', 'key20'}
                      ]
                      
                      const actionTree = [
                          { action: 'create', table: 'tb1', set: 'key1' },
                          { action: 'create', table: 'tb2', set: 'key2' },
                      ...
                          { action: 'create', table: 'tb3', set: 'key24' },
                        ];
                      
                      batches = [];
                      
                      batches = [];
                      
                      batched = () => batches.reduce((p,a)=>[...p,...a],[]);
                      unbatched = () => actionTree.filter(b=>batched().indexOf(b)<0);
                      
                      nextbatchfilter = (a) => (!("input" in a))||(Object.values(a.input).filter(i=>batched().map(a=>a.set).indexOf(i.path[0])<0).length==0);
                      
                      while (unbatched().length>0)
                          batches.push(unbatched().filter(nextbatchfilter));
                          if (batches[batches.length-1].length==0) {
                              console.log("could not build dependency graph with all items, "+unbatched().length.toString()+" items remaining")
                              break; // avoid infinite loop in case of impossible tree
                          }
                      
                      batches = [];
                      
                      unbatched = Array.from(actionTree);
                      
                      nextbatchfilter = (a) => (!("input" in a))||(Object.values(a.input).filter(i=>!(batchedsets.has(i.path[0]))).length==0);
                      
                      batchedsets = new Set();
                      while (unbatched.length>0) {
                          nextbatch = unbatched.filter(nextbatchfilter);
                          if (nextbatch.length==0) {
                              console.log("could not build dependency graph with all items, "+unbatched.length.toString()+" items remaining")
                              break; // avoid infinite loop in case of impossible tree
                          }
                          unbatched = unbatched.filter(a=>!nextbatchfilter(a));
                          batches.push(nextbatch);
                          nextbatch.forEach(a=>batchedsets.add(a.set));
                      }
                      
                      batches.map(b=>Array.from(new Set(b.map(a=>a.table))).map(t=>b.filter(a=>a.table==t)));
                      
                      const actionTree = [
                          { action: 'create', table: 'tb1', set: 'key1' },
                          { action: 'create', table: 'tb2', set: 'key2' },
                      ...
                          { action: 'create', table: 'tb3', set: 'key24' },
                        ];
                      
                      batches = [];
                      
                      batches = [];
                      
                      batched = () => batches.reduce((p,a)=>[...p,...a],[]);
                      unbatched = () => actionTree.filter(b=>batched().indexOf(b)<0);
                      
                      nextbatchfilter = (a) => (!("input" in a))||(Object.values(a.input).filter(i=>batched().map(a=>a.set).indexOf(i.path[0])<0).length==0);
                      
                      while (unbatched().length>0)
                          batches.push(unbatched().filter(nextbatchfilter));
                          if (batches[batches.length-1].length==0) {
                              console.log("could not build dependency graph with all items, "+unbatched().length.toString()+" items remaining")
                              break; // avoid infinite loop in case of impossible tree
                          }
                      
                      batches = [];
                      
                      unbatched = Array.from(actionTree);
                      
                      nextbatchfilter = (a) => (!("input" in a))||(Object.values(a.input).filter(i=>!(batchedsets.has(i.path[0]))).length==0);
                      
                      batchedsets = new Set();
                      while (unbatched.length>0) {
                          nextbatch = unbatched.filter(nextbatchfilter);
                          if (nextbatch.length==0) {
                              console.log("could not build dependency graph with all items, "+unbatched.length.toString()+" items remaining")
                              break; // avoid infinite loop in case of impossible tree
                          }
                          unbatched = unbatched.filter(a=>!nextbatchfilter(a));
                          batches.push(nextbatch);
                          nextbatch.forEach(a=>batchedsets.add(a.set));
                      }
                      
                      batches.map(b=>Array.from(new Set(b.map(a=>a.table))).map(t=>b.filter(a=>a.table==t)));
                      
                      const actionTree = [
                          { action: 'create', table: 'tb1', set: 'key1' },
                          { action: 'create', table: 'tb2', set: 'key2' },
                      ...
                          { action: 'create', table: 'tb3', set: 'key24' },
                        ];
                      
                      batches = [];
                      
                      batches = [];
                      
                      batched = () => batches.reduce((p,a)=>[...p,...a],[]);
                      unbatched = () => actionTree.filter(b=>batched().indexOf(b)<0);
                      
                      nextbatchfilter = (a) => (!("input" in a))||(Object.values(a.input).filter(i=>batched().map(a=>a.set).indexOf(i.path[0])<0).length==0);
                      
                      while (unbatched().length>0)
                          batches.push(unbatched().filter(nextbatchfilter));
                          if (batches[batches.length-1].length==0) {
                              console.log("could not build dependency graph with all items, "+unbatched().length.toString()+" items remaining")
                              break; // avoid infinite loop in case of impossible tree
                          }
                      
                      batches = [];
                      
                      unbatched = Array.from(actionTree);
                      
                      nextbatchfilter = (a) => (!("input" in a))||(Object.values(a.input).filter(i=>!(batchedsets.has(i.path[0]))).length==0);
                      
                      batchedsets = new Set();
                      while (unbatched.length>0) {
                          nextbatch = unbatched.filter(nextbatchfilter);
                          if (nextbatch.length==0) {
                              console.log("could not build dependency graph with all items, "+unbatched.length.toString()+" items remaining")
                              break; // avoid infinite loop in case of impossible tree
                          }
                          unbatched = unbatched.filter(a=>!nextbatchfilter(a));
                          batches.push(nextbatch);
                          nextbatch.forEach(a=>batchedsets.add(a.set));
                      }
                      
                      batches.map(b=>Array.from(new Set(b.map(a=>a.table))).map(t=>b.filter(a=>a.table==t)));
                      
                      const actionTree = [
                          { action: 'create', table: 'tb1', set: 'key1' },
                          { action: 'create', table: 'tb2', set: 'key2' },
                      ...
                          { action: 'create', table: 'tb3', set: 'key24' },
                        ];
                      
                      batches = [];
                      
                      batches = [];
                      
                      batched = () => batches.reduce((p,a)=>[...p,...a],[]);
                      unbatched = () => actionTree.filter(b=>batched().indexOf(b)<0);
                      
                      nextbatchfilter = (a) => (!("input" in a))||(Object.values(a.input).filter(i=>batched().map(a=>a.set).indexOf(i.path[0])<0).length==0);
                      
                      while (unbatched().length>0)
                          batches.push(unbatched().filter(nextbatchfilter));
                          if (batches[batches.length-1].length==0) {
                              console.log("could not build dependency graph with all items, "+unbatched().length.toString()+" items remaining")
                              break; // avoid infinite loop in case of impossible tree
                          }
                      
                      batches = [];
                      
                      unbatched = Array.from(actionTree);
                      
                      nextbatchfilter = (a) => (!("input" in a))||(Object.values(a.input).filter(i=>!(batchedsets.has(i.path[0]))).length==0);
                      
                      batchedsets = new Set();
                      while (unbatched.length>0) {
                          nextbatch = unbatched.filter(nextbatchfilter);
                          if (nextbatch.length==0) {
                              console.log("could not build dependency graph with all items, "+unbatched.length.toString()+" items remaining")
                              break; // avoid infinite loop in case of impossible tree
                          }
                          unbatched = unbatched.filter(a=>!nextbatchfilter(a));
                          batches.push(nextbatch);
                          nextbatch.forEach(a=>batchedsets.add(a.set));
                      }
                      
                      batches.map(b=>Array.from(new Set(b.map(a=>a.table))).map(t=>b.filter(a=>a.table==t)));
                      
                      const actionTree = [
                          { action: 'create', table: 'tb1', set: 'key1' },
                          { action: 'create', table: 'tb2', set: 'key2' },
                      ...
                          { action: 'create', table: 'tb3', set: 'key24' },
                        ];
                      
                      batches = [];
                      
                      batches = [];
                      
                      batched = () => batches.reduce((p,a)=>[...p,...a],[]);
                      unbatched = () => actionTree.filter(b=>batched().indexOf(b)<0);
                      
                      nextbatchfilter = (a) => (!("input" in a))||(Object.values(a.input).filter(i=>batched().map(a=>a.set).indexOf(i.path[0])<0).length==0);
                      
                      while (unbatched().length>0)
                          batches.push(unbatched().filter(nextbatchfilter));
                          if (batches[batches.length-1].length==0) {
                              console.log("could not build dependency graph with all items, "+unbatched().length.toString()+" items remaining")
                              break; // avoid infinite loop in case of impossible tree
                          }
                      
                      batches = [];
                      
                      unbatched = Array.from(actionTree);
                      
                      nextbatchfilter = (a) => (!("input" in a))||(Object.values(a.input).filter(i=>!(batchedsets.has(i.path[0]))).length==0);
                      
                      batchedsets = new Set();
                      while (unbatched.length>0) {
                          nextbatch = unbatched.filter(nextbatchfilter);
                          if (nextbatch.length==0) {
                              console.log("could not build dependency graph with all items, "+unbatched.length.toString()+" items remaining")
                              break; // avoid infinite loop in case of impossible tree
                          }
                          unbatched = unbatched.filter(a=>!nextbatchfilter(a));
                          batches.push(nextbatch);
                          nextbatch.forEach(a=>batchedsets.add(a.set));
                      }
                      
                      batches.map(b=>Array.from(new Set(b.map(a=>a.table))).map(t=>b.filter(a=>a.table==t)));
                      

                      Return value evaluation of a stored function inside a loop with let variable

                      copy iconCopydownload iconDownload
                      function create(i) {
                          // This function closes over `i`
                          const fn = function() {
                              return i;
                          };
                      
                          // This modifies the `i` it closes over
                          ++i;
                      
                          return fn;
                      }
                      const printValue1 = create(1);
                      console.log(printValue1()); // 2 (1 + 1)
                      
                      const printValue27 = create(27);
                      console.log(printValue27()); // 28 (27 + 1)
                      for(var i=0; i<3; i++){
                          setTimeout(() => console.log('var', i))
                      }
                      
                      for(let i=0; i < 3; i++){
                          setTimeout(() => console.log('let',i))
                      }

                      JavaScript: filter array of objects using an object

                      copy iconCopydownload iconDownload
                      function whatIsInAName(collection, source) {
                        const sourceEntries = Object.entries(source);
                        return collection.filter(e =>
                          sourceEntries.every(([key, value]) => e[key] === value)
                        );
                      }
                      
                      console.log(
                        whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" })
                      );
                      console.log(
                        whatIsInAName([{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }], { "apple": 1 })
                      );
                      console.log(
                        whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 }) 
                      );
                      console.log(
                        whatIsInAName([{ "a": 1, "b": 2, "c": 3 }], { "a": 1, "b": 9999, "c": 3 })
                      );
                      function whatIsInAName(collection, source) {
                        const arr = [];
                        let finalObj = collection
                          .map(item => { 
                            const entries = Object.entries(item);
                            console.log(1, entries);
                            return entries;
                          })
                          .filter(el => {
                            console.log(2, String(el), String(Object.values(source)));
                            return String(el).includes(String(Object.values(source)))
                          })
                          .map(el => {
                            const obj = Object.fromEntries(el);
                            console.log(3, obj);
                            return obj;
                          });
                        console.log(4, finalObj);
                        arr.push(finalObj);
                        console.log(5, arr);
                        return arr;
                      }
                          
                      whatIsInAName([{ "apple": 1, "bat": 2 }], { "apple": 1, "bat": 2 });
                      function whatIsInAName(collection, source) {
                        const sourceEntries = Object.entries(source);
                        return collection.filter(e =>
                          sourceEntries.every(([key, value]) => e[key] === value)
                        );
                      }
                      
                      console.log(
                        whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" })
                      );
                      console.log(
                        whatIsInAName([{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }], { "apple": 1 })
                      );
                      console.log(
                        whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 }) 
                      );
                      console.log(
                        whatIsInAName([{ "a": 1, "b": 2, "c": 3 }], { "a": 1, "b": 9999, "c": 3 })
                      );
                      function whatIsInAName(collection, source) {
                        const arr = [];
                        let finalObj = collection
                          .map(item => { 
                            const entries = Object.entries(item);
                            console.log(1, entries);
                            return entries;
                          })
                          .filter(el => {
                            console.log(2, String(el), String(Object.values(source)));
                            return String(el).includes(String(Object.values(source)))
                          })
                          .map(el => {
                            const obj = Object.fromEntries(el);
                            console.log(3, obj);
                            return obj;
                          });
                        console.log(4, finalObj);
                        arr.push(finalObj);
                        console.log(5, arr);
                        return arr;
                      }
                          
                      whatIsInAName([{ "apple": 1, "bat": 2 }], { "apple": 1, "bat": 2 });

                      What the point of spread operaror in JavaScript especially on this example?

                      copy iconCopydownload iconDownload
                      function copyMachine(arr, num) {
                        let newArr = [];
                        while (num >= 1) {
                          // Only change code below this line
                      newArr.push(arr)
                          // Only change code above this line
                          num--;
                        }
                        return newArr;
                      }
                      const oldArr = [true, false, true];
                      const newArr = copyMachine(oldArr, 2);
                      oldArr.push(true);
                      console.log(newArr); // contains an element added to the old array

                      Why does freecodecamp not let my while loop continue?

                      copy iconCopydownload iconDownload
                      function checkall(arr, lcm) {
                        let num1 = arr[0]
                        let num2 = arr[1]
                        // Get the start number
                        let first = (num1 < num2) ? num1 : num2;
                        // Get the end number
                        let last = (num1 > num2) ? num1 : num2;
                        while (first != last) {
                          // Check if lcm is divisble
                          if (lcm % first != 0) {
                            // If not then get an lcm of the number and existing lcm
                            lcm = getlcm(first, lcm)
                          }
                          // Increment first
                          first++
                        }
                        // Return the end lcm
                        return lcm
                      }
                      
                      function smallestCommons(arr) {
                        // Get the two numbers
                        let num1 = arr[0]
                        let num2 = arr[1]
                        // Feed the array and lcm into the checkall function
                        return checkall(arr, getlcm(num1, num2))
                      }
                      
                      function getlcm(num1, num2) {
                        // Get the minimum number out of both
                        let min = (num1 > num2) ? num1 : num2;
                        while (true) {
                          // Check if a number is divisible by both
                          if (min % num1 == 0 && min % num2 == 0) {
                            // If matches, this is the lcm
                            // Break the loop and return the lcm
                            return min
                            break;
                          }
                          // Increment the number
                          min++;
                        }
                      }
                      
                      
                      console.log(smallestCommons([1, 13]))
                      console.log(smallestCommons([23, 18]))
                      console.log(smallestCommons([2, 10]))

                      How does recursion work in a Countdown function

                      copy iconCopydownload iconDownload
                      Array: 1             N: 1 
                      Array: 1,2           N: 2
                      Array: 1,2,3         N: 3
                      Array: 1,2,3,4       N: 4
                      Array: 1,2,3,4,5     N: 5
                      
                      function countup(n) {
                        if (n < 1) {
                          return [];
                        } else {
                          const countArray = countup(n - 1);
                          countArray.push(n);
                          console.log(`countup(${n}) returns ${countArray}`);
                          return countArray;
                        }
                      }
                      console.log(countup(5));
                      function countup(n) {
                        if (n < 1) {
                          console.log('n = %d, returning empty array', n);
                          return [];
                        } else {
                          console.log('n = %d, calling countup(%d - 1)', n, n);
                          const countArray = countup(n - 1);
                          console.log('n = %d, countArray is %s', n, JSON.stringify(countArray))
                          console.log('n = %d, pushing n onto array', n);
                          countArray.push(n);
                          console.log('n = %d, returning %s', n, JSON.stringify(countArray));
                          return countArray;
                        }
                      }
                      console.log(countup(5));
                      // n is 5 and does not change
                      const countArray = countup(n - 1);
                      +-------------------------------------------------------------------------------+
                      |  // n is 4 and does not change                                                |
                      |  const countArray = countup(n - 1);                                           |
                      |  +-------------------------------------------------------------------------+  |
                      |  |  // n is 3 and does not change                                          |  |
                      |  |  const countArray = countup(n - 1);                                     |  |
                      |  |  +-------------------------------------------------------------------+  |  |
                      |  |  |  // n is 2 and does not change                                    |  |  |
                      |  |  |  const countArray = countup(n - 1);                               |  |  |
                      |  |  |  +-------------------------------------------------------------+  |  |  |
                      |  |  |  |  // n is 1 and does not change                              |  |  |  |
                      |  |  |  |  const countArray = countup(n - 1);                         |  |  |  |
                      |  |  |  |  +-------------------------------------------------------+  |  |  |  |
                      |  |  |  |  |  // n is 0 and does not change                        |  |  |  |  |
                      |  |  |  |  |  return []; // the if-block is executed because n < 1 |  |  |  |  |
                      |  |  |  |  +-------------------------------------------------------+  |  |  |  |
                      |  |  |  |  // countArray is []                                        |  |  |  |
                      |  |  |  |  countArray.push(n); // n is still 1                        |  |  |  |
                      |  |  |  |  return countArray; // returns [1]                          |  |  |  |
                      |  |  |  +-------------------------------------------------------------+  |  |  |
                      |  |  |  // countArray is [1]                                             |  |  |
                      |  |  |  countArray.push(n); // n is still 2                              |  |  |
                      |  |  |  return countArray; // returns [1, 2]                             |  |  |
                      |  |  +-------------------------------------------------------------------+  |  |
                      |  |  // countArray is [1, 2]                                                |  |
                      |  |  countArray.push(n); // n is still 3                                    |  |
                      |  |  return countArray; // returns [1, 2, 3]                                |  |
                      |  +-------------------------------------------------------------------------+  |
                      |  // countArray is [1, 2, 3]                                                   |
                      |  countArray.push(n); // n is still 4                                          |
                      |  return countArray; // returns [1, 2, 3, 4]                                   |
                      +-------------------------------------------------------------------------------+
                      // countArray is [1, 2, 3, 4]
                      countArray.push(n); // n is still 5
                      return countArray; // returns [1, 2, 3, 4, 5]
                      

                      Please suggest how to debug

                      copy iconCopydownload iconDownload
                      newArr.push({ name: arr[i].name, orbitalPeriod: orbSecs });
                      
                      newArr.push({ name: arr[i].name, orbitalPeriod: parseInt(orbSecs) });
                      
                      newArr.push({ name: arr[i].name, orbitalPeriod: orbSecs });
                      
                      newArr.push({ name: arr[i].name, orbitalPeriod: parseInt(orbSecs) });
                      

                      Arguments Optional - why do I get a string for arguments (2)([3])?

                      copy iconCopydownload iconDownload
                      function test(){
                      }
                      
                      let test = function(){
                      
                      }
                      
                      function returnfunction(){
                       return function(b){
                                if (typeof b == "number"){
                                  return a + b;
                                }
                              }
                      }
                      let x = returnfunction()
                      
                      function(b){
                                if (typeof b == "number"){
                                  return a + b;
                                }
                      }
                      
                      x = function(){
                      //...
                      }
                      
                      function test(){
                      }
                      
                      let test = function(){
                      
                      }
                      
                      function returnfunction(){
                       return function(b){
                                if (typeof b == "number"){
                                  return a + b;
                                }
                              }
                      }
                      let x = returnfunction()
                      
                      function(b){
                                if (typeof b == "number"){
                                  return a + b;
                                }
                      }
                      
                      x = function(){
                      //...
                      }
                      
                      function test(){
                      }
                      
                      let test = function(){
                      
                      }
                      
                      function returnfunction(){
                       return function(b){
                                if (typeof b == "number"){
                                  return a + b;
                                }
                              }
                      }
                      let x = returnfunction()
                      
                      function(b){
                                if (typeof b == "number"){
                                  return a + b;
                                }
                      }
                      
                      x = function(){
                      //...
                      }
                      
                      function test(){
                      }
                      
                      let test = function(){
                      
                      }
                      
                      function returnfunction(){
                       return function(b){
                                if (typeof b == "number"){
                                  return a + b;
                                }
                              }
                      }
                      let x = returnfunction()
                      
                      function(b){
                                if (typeof b == "number"){
                                  return a + b;
                                }
                      }
                      
                      x = function(){
                      //...
                      }
                      
                      function test(){
                      }
                      
                      let test = function(){
                      
                      }
                      
                      function returnfunction(){
                       return function(b){
                                if (typeof b == "number"){
                                  return a + b;
                                }
                              }
                      }
                      let x = returnfunction()
                      
                      function(b){
                                if (typeof b == "number"){
                                  return a + b;
                                }
                      }
                      
                      x = function(){
                      //...
                      }
                      
                      add(10, 15); // 25
                      var f = add(20);
                      f(18) // 38
                      add(4)(6) // 10
                      
                      function add(a, b) {
                          if (arguments.length == 1) {
                              if (typeof a == "number") {
                                  return function (b) {
                                      if (typeof b == "number") {
                                          return a + b;
                                      }
                                  };
                              } else {
                                  return "undefined";
                              }
                          } else if (arguments.length == 2) {
                              if (typeof a == "number" && typeof b == "number") {
                                  return a + b;
                              } else {
                                  return "undefined";
                              }
                          } else {
                              return "undefined";
                          }
                      }
                      
                      console.log(add(10, 15));
                      var f = add(20);
                      console.log(f(18));
                      console.log(add("xyz"));
                      console.log(add(10, "5"));
                      console.log(add(4)(6));
                      add(10, 15); // 25
                      var f = add(20);
                      f(18) // 38
                      add(4)(6) // 10
                      
                      function add(a, b) {
                          if (arguments.length == 1) {
                              if (typeof a == "number") {
                                  return function (b) {
                                      if (typeof b == "number") {
                                          return a + b;
                                      }
                                  };
                              } else {
                                  return "undefined";
                              }
                          } else if (arguments.length == 2) {
                              if (typeof a == "number" && typeof b == "number") {
                                  return a + b;
                              } else {
                                  return "undefined";
                              }
                          } else {
                              return "undefined";
                          }
                      }
                      
                      console.log(add(10, 15));
                      var f = add(20);
                      console.log(f(18));
                      console.log(add("xyz"));
                      console.log(add(10, "5"));
                      console.log(add(4)(6));

                      trying to understand this profile lookup in JavaScript

                      copy iconCopydownload iconDownload
                      function lookUpProfile(name, prop){
                      // Only change code below this line
                         let hasNoName = true;
                         let hasNoProp = true;
                         for( let i = 0 ; i < contacts.length; i++){
                             const contact = contacts[i];
                             if( contact['firstName'] === name ){
                                 hasNoName = false;
                                 if( contact[prop]){
                                     hasNoProp = false;
                                     return contact[prop];
                                 }
                             }
                         }
                         if( hasNoName ) return "No such contact";
                         if( hasNoProp ) return "No such property";
                      // Only change code above this line
                      }
                      
                      var contacts = [
                          {
                              "firstName": "Akira",
                              "lastName": "Laine",
                              "number": "0543236543",
                              "likes": ["Pizza", "Coding", "Brownie Points"]
                          },
                          {
                              "firstName": "Harry",
                              "lastName": "Potter",
                              "number": "0994372684",
                              "likes": ["Hogwarts", "Magic", "Hagrid"]
                          },
                          {
                              "firstName": "Sherlock",
                              "lastName": "Holmes",
                              "number": "0487345643",
                              "likes": ["Intriguing Cases", "Violin"]
                          },
                          {
                              "firstName": "Kristian",
                              "lastName": "Vos",
                              "number": "unknown",
                              "likes": ["JavaScript", "Gaming", "Foxes"]
                          }
                      ];
                      
                      function lookUpProfile(name, prop){
                      // Only change code below this line
                      
                      //Checking whether the name parametre is equal either to the contacts firstName
                      // or lastName attributes
                      for(let contact of contacts){
                          if(name===contact["firstName"] || name===contact["lastName"]){
                      
                              //Here i check if the attrbute prop exist in the object 
                              if(contact[prop]){
                                  return contact[prop];//it return the value of that attribute if it exists
                              }else{
                                  return "No such property" //The string that i return if it doesn't exist
                              }
                          }
                      }
                      return "No such contact"
                      // Only change code above this line
                      }
                      
                      function lookUpProfile(name, prop){
                      // Only change code below this line
                      for(let i=0;i<contacts.length;i++){
                          if(name===contacts[i]["firstName"] || name===contacts[i]["lastName"]){
                              if(contacts[i][prop]){
                                  return contacts[i][prop];
                              }else{
                                  return "No such property"
                              }
                          }
                      }
                      return "No such contact"
                      // Only change code above this line
                      }
                      
                      var contacts = [
                          {
                              "firstName": "Akira",
                              "lastName": "Laine",
                              "number": "0543236543",
                              "likes": ["Pizza", "Coding", "Brownie Points"]
                          },
                          {
                              "firstName": "Harry",
                              "lastName": "Potter",
                              "number": "0994372684",
                              "likes": ["Hogwarts", "Magic", "Hagrid"]
                          },
                          {
                              "firstName": "Sherlock",
                              "lastName": "Holmes",
                              "number": "0487345643",
                              "likes": ["Intriguing Cases", "Violin"]
                          },
                          {
                              "firstName": "Kristian",
                              "lastName": "Vos",
                              "number": "unknown",
                              "likes": ["JavaScript", "Gaming", "Foxes"]
                          }
                      ];
                      
                      function lookUpProfile(name, prop){
                      // Only change code below this line
                      
                      //Checking whether the name parametre is equal either to the contacts firstName
                      // or lastName attributes
                      for(let contact of contacts){
                          if(name===contact["firstName"] || name===contact["lastName"]){
                      
                              //Here i check if the attrbute prop exist in the object 
                              if(contact[prop]){
                                  return contact[prop];//it return the value of that attribute if it exists
                              }else{
                                  return "No such property" //The string that i return if it doesn't exist
                              }
                          }
                      }
                      return "No such contact"
                      // Only change code above this line
                      }
                      
                      function lookUpProfile(name, prop){
                      // Only change code below this line
                      for(let i=0;i<contacts.length;i++){
                          if(name===contacts[i]["firstName"] || name===contacts[i]["lastName"]){
                              if(contacts[i][prop]){
                                  return contacts[i][prop];
                              }else{
                                  return "No such property"
                              }
                          }
                      }
                      return "No such contact"
                      // Only change code above this line
                      }
                      

                      What is wrong in my regex /(?=^[a-z]+\d{2,})(?=\w{5,})/ pattern?

                      copy iconCopydownload iconDownload
                      if (input.match(/^\D/)
                          && input.match(/\d{2}/)
                          && input.length >= 5) {
                        // password policy fulfilled
                      }
                      
                      (?=^\D.{5,}$).*(?=\d{2,})
                      
                      /(?=\w*\d\d)(?=\w{5,})(?=^[^0-9]\w*)/
                      
                      astr1on11aut
                      ^^^^
                      
                         astr1on11aut
                             ^^
                             ||
                      digit -+|
                              + --- not a digit
                      
                      const regex = /^(?=.{5,})(?!\d)(?=.*\d{2})/;
                      
                      test("abc");
                      test("123");
                      test("123abc");
                      
                      test("abc123");
                      test("astr1on11aut");
                      
                      test("., ;_'@=-%");
                      test("., ;_'@123=-%");
                      
                      function test(string) {
                        console.log(`${string} : ${regex.test(string)}`);
                      }
                      astr1on11aut
                      ^^^^
                      
                         astr1on11aut
                             ^^
                             ||
                      digit -+|
                              + --- not a digit
                      
                      const regex = /^(?=.{5,})(?!\d)(?=.*\d{2})/;
                      
                      test("abc");
                      test("123");
                      test("123abc");
                      
                      test("abc123");
                      test("astr1on11aut");
                      
                      test("., ;_'@=-%");
                      test("., ;_'@123=-%");
                      
                      function test(string) {
                        console.log(`${string} : ${regex.test(string)}`);
                      }
                      astr1on11aut
                      ^^^^
                      
                         astr1on11aut
                             ^^
                             ||
                      digit -+|
                              + --- not a digit
                      
                      const regex = /^(?=.{5,})(?!\d)(?=.*\d{2})/;
                      
                      test("abc");
                      test("123");
                      test("123abc");
                      
                      test("abc123");
                      test("astr1on11aut");
                      
                      test("., ;_'@=-%");
                      test("., ;_'@123=-%");
                      
                      function test(string) {
                        console.log(`${string} : ${regex.test(string)}`);
                      }

                      Community Discussions

                      Trending Discussions on javascript-algorithms
                      • How to sort and chunk a dependency tree of actions, so you can batch as many actions as possible together at each step?
                      • Return value evaluation of a stored function inside a loop with let variable
                      • JavaScript: filter array of objects using an object
                      • What the point of spread operaror in JavaScript especially on this example?
                      • Why does freecodecamp not let my while loop continue?
                      • How does recursion work in a Countdown function
                      • Please suggest how to debug
                      • Arguments Optional - why do I get a string for arguments (2)([3])?
                      • trying to understand this profile lookup in JavaScript
                      • What is wrong in my regex /(?=^[a-z]+\d{2,})(?=\w{5,})/ pattern?
                      Trending Discussions on javascript-algorithms

                      QUESTION

                      How to sort and chunk a dependency tree of actions, so you can batch as many actions as possible together at each step?

                      Asked 2022-Jan-20 at 13:20

                      Say you have a bunch of actions for creating/inserting records into a bunch of different database tables. You have some records which can be inserted without any dependency on the output of any other insert. You have some which need to wait for one other thing to finish. And you have others that need to wait for many things to finish, which might finish at different times in the flow.

                      How can you write an algorithm which would sort and chunk the actions in the dependency tree so the inserts / database actions can be optimally batched? By optimally batched, I mean if you can insert 10 records into the same table at once, then do that. Any time you can batch insert, you should, to minimize the number of database calls/inserts.

                      Here is a snippet from the example code I whipped together with a fake sequence of actions using a simple data structure to capture all the required information.

                      ...
                      { action: 'create', table: 'tb1', set: 'key12', input: {
                        p: { type: 'binding', path: ['key10', 'z'] },
                        q: { type: 'binding', path: ['key11', 'a'] }
                      } },
                      { action: 'create', table: 'tb4', set: 'key13' },
                      { action: 'create', table: 'tb3', set: 'key14' },
                      { action: 'create', table: 'tb4', set: 'key15', input: {
                        a: { type: 'binding', path: ['key8', 'z'] },
                      } },
                      ...
                      

                      Note that there are 4 possible properties on our "dependency node item":

                      • action: This is always "create" in our situation, but potetntially could be other things in the future.
                      • table: The table name to insert into.
                      • set: The name of the variable to add to the shared global "scope" in the action dependency tree, so other actions can read this as input.
                      • input: Inputs to the action, which in our case are all "binding" inputs (but could just as well be literal values, but that would be too easy). For binding inputs, it reads some property/column value from a record stored in the shared scope of the dependency tree.

                      Given that, it should be possible somehow to construct a simple algorithm that chunks the actions into subsets which can be run in parallel AND batched. For example, our code below would end up something like this structure (I manually created this output, so there could be mistakes though I think I got it right. Oh and note, while the tables are numbered, it doesn't imply an order to them necessarily, just were simple names to pick):

                      // this is "close to" the desired result, because
                      // there might be a slightly different sort applied
                      // to this when implemented, but the chunking pattern
                      // and grouping of elements should be exactly like This
                      // (I am pretty sure, I manually did this 
                      // so there could be small mistakes, but I doubt it)
                      const closeToDesiredResult = [
                        [
                          [
                            { action: 'create', table: 'tb1', set: 'key1' },
                            { action: 'create', table: 'tb1', set: 'key21' },
                          ],
                          [
                            { action: 'create', table: 'tb2', set: 'key2' },
                            { action: 'create', table: 'tb2', set: 'key3' },
                            { action: 'create', table: 'tb2', set: 'key23' },
                          ],
                          [
                            { action: 'create', table: 'tb4', set: 'key6' },
                            { action: 'create', table: 'tb4', set: 'key8' },
                            { action: 'create', table: 'tb4', set: 'key13' },
                          ],
                          [
                            { action: 'create', table: 'tb3', set: 'key5' },
                            { action: 'create', table: 'tb3', set: 'key7' },
                            { action: 'create', table: 'tb3', set: 'key9' },
                            { action: 'create', table: 'tb3', set: 'key14' },
                            { action: 'create', table: 'tb3', set: 'key24' },
                          ],
                          [
                            { action: 'create', table: 'tb6', set: 'key17' },
                          ],
                          [
                            { action: 'create', table: 'tb5', set: 'key16' },
                          ]
                        ],
                        [
                          [
                            { action: 'create', table: 'tb1', set: 'key4', input: {
                              x: { type: 'binding', path: ['key2', 'baz'] }
                            } },
                          ],
                          [
                            { action: 'create', table: 'tb3', set: 'key10', input: {
                              y: { type: 'binding', path: ['key6', 'foo'] },
                              z: { type: 'binding', path: ['key1', 'bar'] }
                            } },
                          ],
                          [
                            { action: 'create', table: 'tb4', set: 'key15', input: {
                              a: { type: 'binding', path: ['key8', 'z'] },
                            } },
                          ]
                        ],
                        [
                          [
                            { action: 'create', table: 'tb1', set: 'key12', input: {
                              p: { type: 'binding', path: ['key10', 'z'] },
                              q: { type: 'binding', path: ['key11', 'a'] }
                            } },
                          ],
                          [
                            { action: 'create', table: 'tb4', set: 'key11', input: {
                              a: { type: 'binding', path: ['key10', 'z'] },
                              b: { type: 'binding', path: ['key1', 'bar'] }
                            } },
                          ],
                          [
                            { action: 'create', table: 'tb6', set: 'key18', input: {
                              m: { type: 'binding', path: ['key4', 'x'] },
                            } },
                            { action: 'create', table: 'tb6', set: 'key19', input: {
                              m: { type: 'binding', path: ['key4', 'x'] },
                              n: { type: 'binding', path: ['key13', 'a'] },
                            } },
                          ]
                        ],
                        [
                          [
                            { action: 'create', table: 'tb2', set: 'key22', input: {
                              w: { type: 'binding', path: ['key18', 'm'] },
                              x: { type: 'binding', path: ['key17', 'm'] },
                            } },
                          ],
                          [
                            { action: 'create', table: 'tb6', set: 'key20', input: {
                              m: { type: 'binding', path: ['key18', 'm'] },
                              n: { type: 'binding', path: ['key17', 'm'] },
                            } },
                          ]
                        ]
                      ]
                      

                      Notice how there are 4 top-level chunks in the resulting array. These are the main steps. Then within each step, everything is grouped by table, so they can all be run in parallel, and within each table group, they can all be batch inserted. Boom.

                      How would you implement this, it seems quite tricky for my mind to grasp?

                      const actionTree = generateActionTree()
                      const chunkedActionTree = chunkDependencyTree(actionTree)
                      
                      function chunkDependencyTree(list) {
                        const independentOnesMapByTableName = {}
                        list.forEach(node => {
                          // easy case
                          if (!node.input) {
                            const group = independentOnesMapByTableName[node.table]
                              = independentOnesMapByTableName[node.table] ?? []
                            group.push(node)
                          } else {
                            // I am at a loss for words...
                          }
                        })
                      }
                      
                      function generateActionTree() {
                        // this would be constructed through a bunch of real-world
                        // functions, queuing up all the actions
                        // and pointing outputs to inputs.
                        return [
                          { action: 'create', table: 'tb1', set: 'key1' },
                          { action: 'create', table: 'tb2', set: 'key2' },
                          { action: 'create', table: 'tb2', set: 'key3' },
                          { action: 'create', table: 'tb3', set: 'key5' },
                          { action: 'create', table: 'tb4', set: 'key6' },
                          { action: 'create', table: 'tb3', set: 'key7' },
                          { action: 'create', table: 'tb4', set: 'key8' },
                          { action: 'create', table: 'tb3', set: 'key9' },
                          { action: 'create', table: 'tb3', set: 'key10', input: {
                            y: { type: 'binding', path: ['key6', 'foo'] },
                            z: { type: 'binding', path: ['key1', 'bar'] }
                          } },
                          { action: 'create', table: 'tb1', set: 'key4', input: {
                            x: { type: 'binding', path: ['key2', 'baz'] }
                          } },
                          { action: 'create', table: 'tb4', set: 'key11', input: {
                            a: { type: 'binding', path: ['key10', 'z'] },
                            b: { type: 'binding', path: ['key1', 'bar'] }
                          } },
                          { action: 'create', table: 'tb1', set: 'key12', input: {
                            p: { type: 'binding', path: ['key10', 'z'] },
                            q: { type: 'binding', path: ['key11', 'a'] }
                          } },
                          { action: 'create', table: 'tb4', set: 'key13' },
                          { action: 'create', table: 'tb3', set: 'key14' },
                          { action: 'create', table: 'tb4', set: 'key15', input: {
                            a: { type: 'binding', path: ['key8', 'z'] },
                          } },
                          { action: 'create', table: 'tb5', set: 'key16' },
                          { action: 'create', table: 'tb6', set: 'key17' },
                          { action: 'create', table: 'tb6', set: 'key18', input: {
                            m: { type: 'binding', path: ['key4', 'x'] },
                          } },
                          { action: 'create', table: 'tb6', set: 'key19', input: {
                            m: { type: 'binding', path: ['key4', 'x'] },
                            n: { type: 'binding', path: ['key13', 'a'] },
                          } },
                          { action: 'create', table: 'tb6', set: 'key20', input: {
                            m: { type: 'binding', path: ['key18', 'm'] },
                            n: { type: 'binding', path: ['key17', 'm'] },
                          } },
                          { action: 'create', table: 'tb1', set: 'key21' },
                          { action: 'create', table: 'tb2', set: 'key22', input: {
                            w: { type: 'binding', path: ['key18', 'm'] },
                            x: { type: 'binding', path: ['key17', 'm'] },
                          } },
                          { action: 'create', table: 'tb2', set: 'key23' },
                          { action: 'create', table: 'tb3', set: 'key24' },
                        ]
                      }

                      I think this is roughly topological sorting, but not quite sure how to apply it to this specific situation.

                      ANSWER

                      Answered 2022-Jan-19 at 05:50

                      Your data structure isn't clear to me. What are the single letter ids p, q, etc.? I also don't understand the role of tables. You can insert multiple items in the same table in one write, no? I'm assuming these tihngs don't matter in the root sequencing problem.

                      I'm treating the set field as a "job" and the corresponding keys mentioned in the inputs as dependencies: jobs that must be completed before it.

                      I don't have time to be thorough here, and I don't have a javascript environment handy, so this is in Python.

                      Let's extract a dependency graph from the the verbose data structure. Then look for "levels." The first level is all nodes with no dependencies. The second is all nodes with dependencies met in any previous level, etc. Rinse and repeate.

                      Note unlike I was thinking in my note in comments, this is not a level graph by the traditional definition.

                      Also, I'm not going to bother with data structures to make this efficient. You could do it in O(n log n) time. My code is O(n^2).

                      Sorry if I'm misinterpreting your question. Also sorry for untested, possibly buggy implementation here.

                      from collections import defaultdict
                      
                      def ExtractGraph(cmds):
                        """Gets a dependency graph from verbose command input data."""
                        graph = defaultdict(set)
                        for cmd in cmds:
                          node = cmd['set']
                          graph[node].update(set())
                          inputs = cmd.get('input')
                          if inputs:
                            for _, val in inputs.items():
                              graph[node].add(val['path'][0])
                        return graph
                      
                      def FindSources(graph):
                        """Returns the nodes of the given graph having no dependencies."""
                        sources = set()
                        for node, edges in graph.items():
                          if not edges:
                            sources.add(node)
                        return sources
                      
                      def GetLevels(dependencies):
                        """Returns sequence levels satisfying given dependency graph."""
                        sources = FindSources(dependencies)
                        level = set(sources)
                        done = set(level)
                        todos = dependencies.keys() - done
                        levels = []
                        while level:
                          levels.append(level)
                          # Next level is jobs that have all dependencies done
                          new_level = set()
                          # A clever data structure could find the next level in O(k log n)
                          # for a level size of k and n jobs. This needs O(n).
                          for todo in todos:
                            if dependencies[todo].issubset(done):
                              new_level.add(todo)
                          todos.difference_update(new_level)
                          done.update(new_level)
                          level = new_level
                        return levels
                      
                      cmds = [
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key1' },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key2' },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key3' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key5' },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key6' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key7' },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key8' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key9' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key10', 'input' : {
                            'y' : { 'type' : 'binding', 'path' : ['key6', 'foo'] },
                            'z' : { 'type' : 'binding', 'path' : ['key1', 'bar'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key4', 'input' : {
                            'x' : { 'type' : 'binding', 'path' : ['key2', 'baz'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key11', 'input' : {
                            'a' : { 'type' : 'binding', 'path' : ['key10', 'z'] },
                            'b' : { 'type' : 'binding', 'path' : ['key1', 'bar'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key12', 'input' : {
                            'p' : { 'type' : 'binding', 'path' : ['key10', 'z'] },
                            'q' : { 'type' : 'binding', 'path' : ['key11', 'a'] }
                          } },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key13' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key14' },
                          { 'action' : 'create', 'table' : 'tb4', 'set' : 'key15', 'input' : {
                            'a' : { 'type' : 'binding', 'path' : ['key8', 'z'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb5', 'set' : 'key16' },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key17' },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key18', 'input' : {
                            'm' : { 'type' : 'binding', 'path' : ['key4', 'x'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key19', 'input' : {
                            'm' : { 'type' : 'binding', 'path' : ['key4', 'x'] },
                            'n' : { 'type' : 'binding', 'path' : ['key13', 'a'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb6', 'set' : 'key20', 'input' : {
                            'm' : { 'type' : 'binding', 'path' : ['key18', 'm'] },
                            'n' : { 'type' : 'binding', 'path' : ['key17', 'm'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb1', 'set' : 'key21' },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key22', 'input' : {
                            'w' : { 'type' : 'binding', 'path' : ['key18', 'm'] },
                            'x' : { 'type' : 'binding', 'path' : ['key17', 'm'] },
                          } },
                          { 'action' : 'create', 'table' : 'tb2', 'set' : 'key23' },
                          { 'action' : 'create', 'table' : 'tb3', 'set' : 'key24' },
                      ]
                          
                      dependencies = ExtractGraph(cmds)
                      levels = GetLevels(dependencies)
                      print(levels)
                      

                      When run, this finds a few levels:

                      [
                      {'key9', 'key3', 'key24', 'key7', 'key17', 'key8', 'key21', 'key1',
                           'key5', 'key2', 'key16', 'key6', 'key23', 'key13', 'key14'}, 
                      {'key15', 'key4', 'key10'}, 
                      {'key19', 'key18', 'key11'}, 
                      {'key22', 'key12', 'key20'}
                      ]
                      

                      For a spot check, let's look at key12. It has 10 and 11 as dependencies. key10 has 6 and 1. key11 has 10 and 1. keys 1 and 6 have none. We find

                      • 1 and 6 (no dependencies) in level 0,
                      • 10 (needs 1 and 6) in level 1,
                      • 11 (needs 10 and 1) in level 2,
                      • 12 (needs 10 and 11) in level 3.

                      Each job is being done as soon as its dependencies are met. So that's encouraging. More thorough testing is a must, however.

                      If you need to group these levels further into separate inserts per table, that's a post-processing step. The resulting inserts within a level can be done in parallel.

                      Source https://stackoverflow.com/questions/70725279

                      Community Discussions, Code Snippets contain sources that include Stack Exchange Network

                      Vulnerabilities

                      No vulnerabilities reported

                      Install javascript-algorithms

                      You can install using 'npm i javascript-algorithms-and-data-structures' or download it from GitHub, npm.

                      Support

                      For any new features, suggestions and bugs create an issue on GitHub. If you have any questions check and ask questions on community page Stack Overflow .

                      DOWNLOAD this Library from

                      Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
                      over 430 million Knowledge Items
                      Find more libraries
                      Reuse Solution Kits and Libraries Curated by Popular Use Cases
                      Explore Kits

                      Save this library and start creating your kit

                      Explore Related Topics

                      Share this Page

                      share link
                      Consider Popular Learning Libraries
                      Try Top Libraries by trekhleb
                      Compare Learning Libraries with Highest Support
                      Compare Learning Libraries with Highest Quality
                      Compare Learning Libraries with Highest Security
                      Compare Learning Libraries with Permissive License
                      Compare Learning Libraries with Highest Reuse
                      Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
                      over 430 million Knowledge Items
                      Find more libraries
                      Reuse Solution Kits and Libraries Curated by Popular Use Cases
                      Explore Kits

                      Save this library and start creating your kit

                      • © 2022 Open Weaver Inc.