diff --git a/README.md b/README.md index 7e34acf9e..812f7c70e 100644 --- a/README.md +++ b/README.md @@ -344,6 +344,7 @@ average(1, 2, 3); * [`matches`](#matches) * [`matchesWith`](#matcheswith) * [`merge`](#merge) +* [`nest`](#nest) * [`objectFromPairs`](#objectfrompairs) * [`objectToPairs`](#objecttopairs) * [`omit`](#omit) @@ -6259,6 +6260,46 @@ merge(object, other); // { a: [ { x: 2 }, { y: 4 }, { z: 3 } ], b: [ 1, 2, 3 ],
[⬆ Back to top](#table-of-contents) +### nest + +Given a flat array of objects linked to one another, it will nest them recursively. +Useful for nesting comments, such as the ones on reddit.com. + +Use recursion. Use `Array.filter()` to filter the items where the `id` matches the `link`, +then use `Array.map()` to map each one to a new object that has a `children` property which +recursively nests the items based on which ones are children of the current item. Omit the second +argument, `id`, to default to `null` which indicates the object is not linked to another one (i.e., +it is a top level). Omit the third argument, `link`, to use `'parent_id'` as the default property +which links the object to another one by its `id`. + +```js +const nest = (items, id = null, link = 'parent_id') => + items + .filter(item => item[link] === id) + .map(item => ({ ...item, children: nest(items, item.id) })); +``` + +
+Examples + +```js +// One top level comment +const comments = [ + { id: 1, parent_id: null }, + { id: 2, parent_id: 1 }, + { id: 3, parent_id: 1 }, + { id: 4, parent_id: 2 }, + { id: 5, parent_id: 4 } +]; +const nestedComments = nest(comments); // [{ id: 1, parent_id: null, children: [...] }] +``` + + +
+ +
[⬆ Back to top](#table-of-contents) + + ### objectFromPairs Creates an object from the given key-value pairs. diff --git a/docs/index.html b/docs/index.html index a6ec001a6..c214aacdb 100644 --- a/docs/index.html +++ b/docs/index.html @@ -74,7 +74,7 @@ document.getElementById('doc-drawer-checkbox').checked = false; } }, false); - }

logo 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

 

Adapter

ary

Creates a function that accepts up to n arguments, ignoring any additional arguments.

Call the provided function, fn, with up to n arguments, using Array.slice(0,n) and the spread operator (...).

const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
+      }

logo 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

 

Adapter

ary

Creates a function that accepts up to n arguments, ignoring any additional arguments.

Call the provided function, fn, with up to n arguments, using Array.slice(0,n) and the spread operator (...).

const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
 
const firstTwoMax = ary(Math.max, 2);
 [[2, 6, 'a'], [8, 4, 6], [10]].map(x => firstTwoMax(...x)); // [6, 8, 10]
 

call

Given a key and a set of arguments, call them when given a context. Primarily useful in composition.

Use a closure to call a stored key with stored arguments.

const call = (key, ...args) => context => context[key](...args);
@@ -1476,6 +1476,19 @@ Foo.prototype: 'foo'
 };
 merge(object, other); // { a: [ { x: 2 }, { y: 4 }, { z: 3 } ], b: [ 1, 2, 3 ], c: 'foo' }
+

nest

Given a flat array of objects linked to one another, it will nest them recursively. Useful for nesting comments, such as the ones on reddit.com.

Use recursion. Use Array.filter() to filter the items where the id matches the link, then use Array.map() to map each one to a new object that has a children property which recursively nests the items based on which ones are children of the current item. Omit the second argument, id, to default to null which indicates the object is not linked to another one (i.e., it is a top level). Omit the third argument, link, to use 'parent_id' as the default property which links the object to another one by its id.

const nest = (items, id = null, link = 'parent_id') =>
+  items
+    .filter(item => item[link] === id)
+    .map(item => ({ ...item, children: nest(items, item.id) }));
+
// One top level comment
+const comments = [
+  { id: 1, parent_id: null },
+  { id: 2, parent_id: 1 },
+  { id: 3, parent_id: 1 },
+  { id: 4, parent_id: 2 },
+  { id: 5, parent_id: 4 }
+];
+const nestedComments = nest(comments); // [{ id: 1, parent_id: null, children: [...] }]
 

objectFromPairs

Creates an object from the given key-value pairs.

Use Array.reduce() to create and combine key-value pairs.

const objectFromPairs = arr => arr.reduce((a, v) => ((a[v[0]] = v[1]), a), {});
 
objectFromPairs([['a', 1], ['b', 2]]); // {a: 1, b: 2}
 

objectToPairs

Creates an array of key-value pair arrays from an object.

Use Object.keys() and Array.map() to iterate over the object's keys and produce an array with key-value pairs.

const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]);
diff --git a/snippets/nest.md b/snippets/nest.md
index 40eb911c7..616098748 100644
--- a/snippets/nest.md
+++ b/snippets/nest.md
@@ -12,7 +12,9 @@ which links the object to another one by its `id`.
 
 ```js
 const nest = (items, id = null, link = 'parent_id') =>
-  items.filter(item => item[link] === id).map(item => ({ ...item, children: nest(items, item.id) }))
+  items
+    .filter(item => item[link] === id)
+    .map(item => ({ ...item, children: nest(items, item.id) }));
 ```
 
 ```js
@@ -23,7 +25,7 @@ const comments = [
   { id: 3, parent_id: 1 },
   { id: 4, parent_id: 2 },
   { id: 5, parent_id: 4 }
-]
-const nestedComments = nest(comments) // [{ id: 1, parent_id: null, children: [...] }]
+];
+const nestedComments = nest(comments); // [{ id: 1, parent_id: null, children: [...] }]
 ```