Full Code of alferov/array-to-tree for AI

master 85db84516e62 cached
10 files
13.5 KB
3.9k tokens
6 symbols
1 requests
Download .txt
Repository: alferov/array-to-tree
Branch: master
Commit: 85db84516e62
Files: 10
Total size: 13.5 KB

Directory structure:
gitextract_m8yvd90x/

├── .eslintrc
├── .gitignore
├── .prettierrc
├── .travis.yml
├── index.d.ts
├── index.js
├── license.md
├── package.json
├── readme.md
└── test/
    └── test.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .eslintrc
================================================
{
  "extends": "eslint:recommended",
  "rules": {
    "comma-dangle": "off"
  },
  "env": {
    "browser": true,
    "node": true,
    "mocha": true
  },
  "parserOptions": {
    "ecmaVersion": 6
  }
}


================================================
FILE: .gitignore
================================================
node_modules
bower_components


================================================
FILE: .prettierrc
================================================
{
  "singleQuote": true,
  "trailingComma": "none"
}


================================================
FILE: .travis.yml
================================================
sudo: false
language: node_js
cache:
  directories:
    - node_modules
notifications:
  email: false
node_js:
  - 'stable'
  - '6'
branches:
  except:
    - "/^v\\d+\\.\\d+\\.\\d+$/"


================================================
FILE: index.d.ts
================================================
export = arrayToTree;

declare function arrayToTree<T>(data: T[], options?: Partial<arrayToTree.Options>): Array<arrayToTree.Tree<T>>;

declare namespace arrayToTree {
	interface Options {
		childrenProperty: string;
		parentProperty: string;
		customID: string;
		rootID: string;
	}

	type Tree<T> = T & {
		children?: Array<Tree<T>>;
	};
}


================================================
FILE: index.js
================================================
'use strict';
var property = require('nested-property');
var keyBy = require('lodash.keyby');

function createTree(array, rootNodes, customID, childrenProperty) {
  var tree = [];

  for (var rootNode in rootNodes) {
    var node = rootNodes[rootNode];
    var childNode = array[node[customID]];

    if (!node && !rootNodes.hasOwnProperty(rootNode)) {
      continue;
    }

    if (childNode) {
      node[childrenProperty] = createTree(
        array,
        childNode,
        customID,
        childrenProperty
      );
    }

    tree.push(node);
  }

  return tree;
}

function groupByParents(array, options) {
  var arrayByID = keyBy(array, options.customID);

  return array.reduce(function(prev, item) {
    var parentID = property.get(item, options.parentProperty);
    if (!parentID || !arrayByID.hasOwnProperty(parentID)) {
      parentID = options.rootID;
    }

    if (parentID && prev.hasOwnProperty(parentID)) {
      prev[parentID].push(item);
      return prev;
    }

    prev[parentID] = [item];
    return prev;
  }, {});
}

function isObject(o) {
  return Object.prototype.toString.call(o) === '[object Object]';
}

function deepClone(data) {
  if (Array.isArray(data)) {
    return data.map(deepClone);
  } else if (isObject(data)) {
    return Object.keys(data).reduce(function(o, k) {
      o[k] = deepClone(data[k]);
      return o;
    }, {});
  } else {
    return data;
  }
}

/**
 * arrayToTree
 * Convert a plain array of nodes (with pointers to parent nodes) to a nested
 * data structure
 *
 * @name arrayToTree
 * @function
 *
 * @param {Array} data An array of data
 * @param {Object} options An object containing the following fields:
 *
 *  - `parentProperty` (String): A name of a property where a link to
 * a parent node could be found. Default: 'parent_id'
 *  - `customID` (String): An unique node identifier. Default: 'id'
 *  - `childrenProperty` (String): A name of a property where children nodes
 * are going to be stored. Default: 'children'.
 *
 * @return {Array} Result of transformation
 */

module.exports = function arrayToTree(data, options) {
  options = Object.assign(
    {
      parentProperty: 'parent_id',
      childrenProperty: 'children',
      customID: 'id',
      rootID: '0'
    },
    options
  );

  if (!Array.isArray(data)) {
    throw new TypeError('Expected an array but got an invalid argument');
  }

  var grouped = groupByParents(deepClone(data), options);
  return createTree(
    grouped,
    grouped[options.rootID],
    options.customID,
    options.childrenProperty
  );
};


================================================
FILE: license.md
================================================
Copyright © 2016 Philipp Alferov.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: package.json
================================================
{
  "name": "array-to-tree",
  "version": "3.3.2",
  "description": "Convert a plain array of nodes (with pointers to parent nodes) to a tree",
  "main": "index.js",
  "scripts": {
    "test": "mocha --reporter nyan",
    "tdd": "npm test -- --watch",
    "release": "npm version ${BUMP:-\"patch\"} --no-git-tag-version && git add package.json package-lock.json && git commit -m \":octocat: Bump to $(cat package.json | json version)\" && git tag $(cat package.json | json version)",
    "release:major": "BUMP=major npm run release",
    "release:minor": "BUMP=minor npm run release"
  },
  "repository": "alferov/array-to-tree",
  "keywords": [
    "array",
    "list",
    "pointer",
    "parent",
    "tree",
    "navigation",
    "nested"
  ],
  "devDependencies": {
    "chai": "^4.1.2",
    "eslint": "^5.4.0",
    "json": "^9.0.3",
    "mocha": "^5.2.0"
  },
  "author": {
    "name": "Philipp Alferov",
    "email": "philipp.alferov@gmail.com"
  },
  "engines": {
    "node": ">=4"
  },
  "license": "MIT",
  "dependencies": {
    "lodash.keyby": "^4.6.0",
    "nested-property": "^0.0.7"
  }
}


================================================
FILE: readme.md
================================================
# array-to-tree

[![Build Status][travis-image]][travis-url] [![Dependency Status][depstat-image]][depstat-url]

![array-to-tree](media/array-to-tree.png)

> Convert a plain array of nodes (with pointers to parent nodes) to a nested data structure.

Solves a problem with conversion of retrieved from a database sets of data to a nested data structure (i.e. navigation tree).

## Installation

```bash
$ npm install array-to-tree --save
```

## Usage

```js
var arrayToTree = require('array-to-tree');

var dataOne = [
  {
    id: 1,
    name: 'Portfolio',
    parent_id: undefined
  },
  {
    id: 2,
    name: 'Web Development',
    parent_id: 1
  },
  {
    id: 3,
    name: 'Recent Works',
    parent_id: 2
  },
  {
    id: 4,
    name: 'About Me',
    parent_id: undefined
  }
];

arrayToTree(dataOne);

/*
 * Output:
 *
 * Portfolio
 *   Web Development
 *     Recent Works
 * About Me
 */

var dataTwo = [
  {
    _id: 'ec654ec1-7f8f-11e3-ae96-b385f4bc450c',
    name: 'Portfolio',
    parent: null
  },
  {
    _id: 'ec666030-7f8f-11e3-ae96-0123456789ab',
    name: 'Web Development',
    parent: 'ec654ec1-7f8f-11e3-ae96-b385f4bc450c'
  },
  {
    _id: 'ec66fc70-7f8f-11e3-ae96-000000000000',
    name: 'Recent Works',
    parent: 'ec666030-7f8f-11e3-ae96-0123456789ab'
  },
  {
    _id: '32a4fbed-676d-47f9-a321-cb2f267e2918',
    name: 'About Me',
    parent: null
  }
];

arrayToTree(dataTwo, {
  parentProperty: 'parent',
  customID: '_id'
});

/*
 * Output:
 *
 * Portfolio
 *   Web Development
 *     Recent Works
 * About Me
 */
```

## API

### `arrayToTree(data, [options])`

Convert a plain array of nodes (with pointers to parent nodes) to a a nested data structure.

#### Parameters

- **Array** `data`: An array of data
- **Object** `options`: An object containing the following fields:
  - `parentProperty` (String): A name of a property where a link to a parent node could be found. Default: 'parent_id'.
  - `childrenProperty` (String): A name of a property where children nodes are going to be stored. Default: 'children'.
  - `customID` (String): An unique node identifier. Default: 'id'.

#### Return

- **Array**: Result of transformation

## License

MIT © [Philipp Alferov](https://github.com/alferov)

[travis-url]: https://travis-ci.org/alferov/array-to-tree
[travis-image]: https://img.shields.io/travis/alferov/array-to-tree.svg?style=flat-square
[depstat-url]: https://david-dm.org/alferov/array-to-tree
[depstat-image]: https://david-dm.org/alferov/array-to-tree.svg?style=flat-square


================================================
FILE: test/test.js
================================================
'use strict';
var chai = require('chai');
var expect = chai.expect;
var toTree = require('../index.js');

var initial = [
  {
    id: 1,
    parent_id: null,
    children: [{ id: 5 }]
  },
  {
    id: 2,
    parent_id: 1
  },
  {
    id: 3,
    parent_id: 2
  },
  {
    id: 4,
    parent_id: null
  }
];

var current;

describe('array-to-tree', function() {
  describe('with default arguments', function() {
    beforeEach(function() {
      current = toTree(initial);
    });

    it('should not modify given array', function() {
      expect(initial[0]).to.be.deep.equal({
        id: 1,
        parent_id: null,
        children: [{ id: 5 }]
      });
    });

    it('should return an array', function() {
      expect(current).to.be.an('array');
    });

    it('should keep parent_id property', function() {
      var first = current[0];
      expect(first).to.have.property('parent_id');
    });

    it('should create nested objects with children', function() {
      var first = current[0];
      expect(first)
        .to.have.property('children')
        .that.is.an('array')
        .to.have.length.of.at.least(1);
    });

    it('should return an expected value', function() {
      expect(current).to.be.deep.equal([
        {
          id: 1,
          parent_id: null,
          children: [
            {
              id: 2,
              parent_id: 1,
              children: [
                {
                  id: 3,
                  parent_id: 2
                }
              ]
            }
          ]
        },
        {
          id: 4,
          parent_id: null
        }
      ]);
    });
  });

  describe('with invalid arguments', function() {
    it('should return an empty array if the empty array passed', function() {
      expect(toTree([])).to.be.deep.equal([]);
    });

    it('should throw an error if wrong arguments passed', function() {
      expect(toTree.bind(null, 'string')).to.throw(/invalid argument/);
      expect(toTree.bind(null, {})).to.throw(/invalid argument/);
    });

    it('returns the same array if there is no pointer to parent', function() {
      var modified = initial.map(function(item) {
        delete item.parent_id;
        return item;
      });
      expect(toTree(modified)).to.be.deep.equal(modified);
    });
  });

  describe('with custom arguments', function() {
    it('should work with custom parents links', function() {
      expect(
        toTree(
          [
            {
              _id: 'ec654ec1-7f8f-11e3-ae96-b385f4bc450c',
              parent: null
            },
            {
              _id: 'ec666030-7f8f-11e3-ae96-0123456789ab',
              parent: 'ec654ec1-7f8f-11e3-ae96-b385f4bc450c'
            },
            {
              _id: 'ec66fc70-7f8f-11e3-ae96-000000000000',
              parent: 'ec666030-7f8f-11e3-ae96-0123456789ab'
            },
            {
              _id: '32a4fbed-676d-47f9-a321-cb2f267e2918',
              parent: null
            }
          ],
          {
            parentProperty: 'parent',
            customID: '_id',
            childrenProperty: '_children'
          }
        )
      ).to.be.deep.equal([
        {
          _id: 'ec654ec1-7f8f-11e3-ae96-b385f4bc450c',
          parent: null,
          _children: [
            {
              _id: 'ec666030-7f8f-11e3-ae96-0123456789ab',
              parent: 'ec654ec1-7f8f-11e3-ae96-b385f4bc450c',
              _children: [
                {
                  _id: 'ec66fc70-7f8f-11e3-ae96-000000000000',
                  parent: 'ec666030-7f8f-11e3-ae96-0123456789ab'
                }
              ]
            }
          ]
        },
        {
          _id: '32a4fbed-676d-47f9-a321-cb2f267e2918',
          parent: null
        }
      ]);
    });

    it('should work with nested parent id', function() {
      expect(
        toTree(
          [
            {
              id: 1,
              attributes: {
                name: 'Parent',
                parent_id: null
              }
            },
            {
              id: 2,
              attributes: {
                name: 'Child One',
                parent_id: 1
              }
            },
            {
              id: 3,
              attributes: {
                name: 'Child Two',
                parent_id: 1
              }
            }
          ],
          {
            parentProperty: 'attributes.parent_id'
          }
        )
      ).to.be.deep.equal([
        {
          id: 1,
          attributes: {
            name: 'Parent',
            parent_id: null
          },
          children: [
            {
              id: 2,
              attributes: {
                name: 'Child One',
                parent_id: 1
              }
            },
            {
              id: 3,
              attributes: {
                name: 'Child Two',
                parent_id: 1
              }
            }
          ]
        }
      ]);
    });

    it('should work with orphan nodes', function() {
      expect(
        toTree([
          {
            id: 1,
            parent_id: null
          },
          {
            id: 2,
            parent_id: 1
          },
          {
            id: 3,
            parent_id: 2
          },
          {
            id: 4,
            parent_id: 5
          }
        ])
      ).to.be.deep.equal([
        {
          id: 1,
          parent_id: null,
          children: [
            {
              id: 2,
              parent_id: 1,
              children: [
                {
                  id: 3,
                  parent_id: 2
                }
              ]
            }
          ]
        },
        {
          id: 4,
          parent_id: 5
        }
      ]);
    });
  });
});
Download .txt
gitextract_m8yvd90x/

├── .eslintrc
├── .gitignore
├── .prettierrc
├── .travis.yml
├── index.d.ts
├── index.js
├── license.md
├── package.json
├── readme.md
└── test/
    └── test.js
Download .txt
SYMBOL INDEX (6 symbols across 2 files)

FILE: index.d.ts
  type Options (line 6) | interface Options {
  type Tree (line 13) | type Tree<T> = T & {

FILE: index.js
  function createTree (line 5) | function createTree(array, rootNodes, customID, childrenProperty) {
  function groupByParents (line 31) | function groupByParents(array, options) {
  function isObject (line 50) | function isObject(o) {
  function deepClone (line 54) | function deepClone(data) {
Condensed preview — 10 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (15K chars).
[
  {
    "path": ".eslintrc",
    "chars": 202,
    "preview": "{\n  \"extends\": \"eslint:recommended\",\n  \"rules\": {\n    \"comma-dangle\": \"off\"\n  },\n  \"env\": {\n    \"browser\": true,\n    \"no"
  },
  {
    "path": ".gitignore",
    "chars": 30,
    "preview": "node_modules\nbower_components\n"
  },
  {
    "path": ".prettierrc",
    "chars": 53,
    "preview": "{\n  \"singleQuote\": true,\n  \"trailingComma\": \"none\"\n}\n"
  },
  {
    "path": ".travis.yml",
    "chars": 183,
    "preview": "sudo: false\nlanguage: node_js\ncache:\n  directories:\n    - node_modules\nnotifications:\n  email: false\nnode_js:\n  - 'stabl"
  },
  {
    "path": "index.d.ts",
    "chars": 342,
    "preview": "export = arrayToTree;\n\ndeclare function arrayToTree<T>(data: T[], options?: Partial<arrayToTree.Options>): Array<arrayTo"
  },
  {
    "path": "index.js",
    "chars": 2559,
    "preview": "'use strict';\nvar property = require('nested-property');\nvar keyBy = require('lodash.keyby');\n\nfunction createTree(array"
  },
  {
    "path": "license.md",
    "chars": 1058,
    "preview": "Copyright © 2016 Philipp Alferov.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this "
  },
  {
    "path": "package.json",
    "chars": 1104,
    "preview": "{\n  \"name\": \"array-to-tree\",\n  \"version\": \"3.3.2\",\n  \"description\": \"Convert a plain array of nodes (with pointers to pa"
  },
  {
    "path": "readme.md",
    "chars": 2522,
    "preview": "# array-to-tree\n\n[![Build Status][travis-image]][travis-url] [![Dependency Status][depstat-image]][depstat-url]\n\n![array"
  },
  {
    "path": "test/test.js",
    "chars": 5761,
    "preview": "'use strict';\nvar chai = require('chai');\nvar expect = chai.expect;\nvar toTree = require('../index.js');\n\nvar initial = "
  }
]

About this extraction

This page contains the full source code of the alferov/array-to-tree GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 10 files (13.5 KB), approximately 3.9k tokens, and a symbol index with 6 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!