{"_id":"@alisatelier/lotide","_rev":"2-c3fb87218b86dfd4b797d948ff240a2e","name":"@alisatelier/lotide","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@alisatelier/lotide","version":"1.0.0","author":{"name":"alisatelier"},"license":"ISC","_id":"@alisatelier/lotide@1.0.0","maintainers":[{"name":"alisatelier","email":"ali.buchwald@proton.me"}],"homepage":"https://github.com/alisatelier/lotide#readme","bugs":{"url":"https://github.com/alisatelier/lotide/issues"},"dist":{"shasum":"39d59d5d33bab0345b9044fd7374fe83e9b2f6ee","tarball":"https://registry.npmjs.org/@alisatelier/lotide/-/lotide-1.0.0.tgz","fileCount":36,"integrity":"sha512-aKox+EQ1Vbq0HxB9QhdBu6et2k71xDVkRJWY6mUibszYBIHacQtONkVruNxB9Kn1jWGgbr8pc+A0mpkeXy9fTw==","signatures":[{"sig":"MEQCICTiKU2ZuUtz9atynNjUBNis/cG4EFztgmig9qA14UrDAiBE+DjgUuc7t63jM7s1lzF4A5p8raQgcdBGY+b/MNlP+Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33069},"main":"assertArraysEqual.js","gitHead":"78567fd0d041e13b9a18696f29a5262ca141673a","scripts":{"test":"mocha"},"_npmUser":{"name":"alisatelier","actor":{"name":"alisatelier","type":"user","email":"ali.buchwald@proton.me"},"email":"ali.buchwald@proton.me"},"repository":{"url":"git+https://github.com/alisatelier/lotide.git","type":"git"},"_npmVersion":"8.19.4","description":"A simplified clone of Lodash implementing core utility functions for arrays and objects. Built for educational use","directories":{"test":"test"},"_nodeVersion":"16.20.2","_hasShrinkwrap":false,"devDependencies":{"chai":"^4.3.1","mocha":"^9.2.2"},"_npmOperationalInternal":{"tmp":"tmp/lotide_1.0.0_1751964624918_0.9328483050339316","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@alisatelier/lotide","version":"1.0.1","description":"A simplified clone of Lodash implementing core utility functions for arrays and objects. Built for educational use","main":"index.js","directories":{"test":"test"},"scripts":{"test":"mocha"},"repository":{"type":"git","url":"git+https://github.com/alisatelier/lotide.git"},"author":{"name":"alisatelier"},"license":"ISC","bugs":{"url":"https://github.com/alisatelier/lotide/issues"},"homepage":"https://github.com/alisatelier/lotide#readme","devDependencies":{"chai":"^4.3.1","mocha":"^9.2.2"},"gitHead":"da19b64dc4e329d63d09732231eeebec922e9891","_id":"@alisatelier/lotide@1.0.1","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-2tSpLFxk2rU8Z5n6epu+uO7FMXqreL4pkwSmFS+KMwW5Ewj/9QBkR1HJO/tokMl8+Q+7OQzr4ow+jH567NqrFg==","shasum":"f365349453e96802be6145eba14903e96d1d8e2f","tarball":"https://registry.npmjs.org/@alisatelier/lotide/-/lotide-1.0.1.tgz","fileCount":36,"unpackedSize":33057,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFL5y4s5OH4HmlaiMWGv6L2uLQ8aM+2o4y18sx8sPh75AiAInAudbOY6/2xBKMzfhursxwJ/3NYNVrZ3FEe37wb+IQ=="}]},"_npmUser":{"name":"alisatelier","email":"ali.buchwald@proton.me","actor":{"name":"alisatelier","email":"ali.buchwald@proton.me","type":"user"}},"maintainers":[{"name":"alisatelier","email":"ali.buchwald@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/lotide_1.0.1_1752009762804_0.6415990048492615"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-08T08:50:24.771Z","modified":"2025-07-08T21:22:43.207Z","1.0.0":"2025-07-08T08:50:25.392Z","1.0.1":"2025-07-08T21:22:42.976Z"},"bugs":{"url":"https://github.com/alisatelier/lotide/issues"},"author":{"name":"alisatelier"},"license":"ISC","homepage":"https://github.com/alisatelier/lotide#readme","repository":{"type":"git","url":"git+https://github.com/alisatelier/lotide.git"},"description":"A simplified clone of Lodash implementing core utility functions for arrays and objects. Built for educational use","maintainers":[{"name":"alisatelier","email":"ali.buchwald@proton.me"}],"readme":"# Lotide\n\nA mini clone of the [Lodash](https://lodash.com) library.\n\n## Purpose\n\n**_BEWARE:_ This library was published for learning purposes. It is _not_ intended for use in production-grade software.**\n\nThis project was created and published by me as part of my learnings at Lighthouse Labs.\n\n## Usage\n\n**Install it:**\n\n`npm install @alisatelier/lotide`\n\n**Require it:**\n\n`const _ = require('@alisatelier/lotide');`\n\n**Call it:**\n\n`const results = _.tail([1, 2, 3]) // => [2, 3]`\n\n## Documentation\n\nThe following functions are currently implemented:\n\n- #### [countLetters()](./countLetters.js) : countLetters function takes a string and returns an object where each key is a letter (excluding spaces), and its value is the number of times that letter appears in the string.\n\n  example: Given the string: \"My Intuition Made Me Do It\" (The title of my published book), this function returns an object of the number of times each letter appears. { M: 3, y: 1, I: 3, n: 2, t: 3, u: 1, i: 3, o: 2, a: 1, d: 2, e: 2 }\n\n  ```js\n  countLetters(\"My Intuition Made Me Do It\");\n  //returns { M: 3, y: 1, I: 3, n: 2, t: 3, u: 1, i: 3, o: 2, a: 1, d: 2, e: 2 }\n  ```\n\n- #### [countOnly()](./countOnly.js) : takes an array (allItems) and an object (itemsToCount) that specifies which items to count (with true values). It returns a new object with counts of only the specified items that appear in the array.\n\n  example: You're doing inventory of a collection of products and want to include some products in your inventory, but not others. You don't want collect them all. By scanning (allItems), you only count the products you are collecting inventory of.\n\n  ```javascript\n  const allItems = [\"Norse Runes\", \"Rune Cloth\", \"Tarot Deck\", \"Journal\"];\n  const itemsToCount = {\n    \"Norse Runes\": true,\n    \"Rune Cloth\": true,\n    \"Tarot Deck\": true,\n    Journal: false,\n  };\n\n  countOnly(allItems, itemsToCount);\n  // returns { \"Norse Runes\": 1, \"Rune Cloth\": 1, \"Tarot Deck\": 1 }\n  ```\n\n- #### [eqObjects()](./eqObjects.js) : eqObjects function compares two objects and returns true if they have the same keys with equal values. It handles both primitive values and arrays, using a helper function to compare array contents accurately.\n\n  example: the following would return true, because the key/value pairs are identical in both objects.\n\n  ```javascript\n  const obj1 = {\n    writing: \"A Courtship of Karma and Cosmos\",\n    listeningTo: \"Collection of Bridgerton Soundtracks\",\n  };\n\n  const obj2 = {\n    writing: \"A Courtship of Karma and Cosmos\",\n    listeningTo: \"Collection of Bridgerton Soundtracks\",\n  };\n  ```\n\n- #### [findKey()](./findKey.js) : findKey searches through an object and returns the first key for which the provided callback returns true. If no match is found, it returns undefined.\n\n  example: In this example, findKey is used to search the planets object for the first key whose rules property is equal to \"Gemini\". The function returns \"Mercury\", since Mercury is the first planet listed that rules Gemini.\n\n  ```javascript\n  const planets = {\n    Sun: { rules: \"Leo\" },\n    Moon: { rules: \"Cancer\" },\n    Mercury: { rules: \"Gemini\" },\n  };\n\n  findKey(planets, (obj) => obj.rules === \"Gemini\");\n  // returns: Mercury\n  ```\n\n- #### [findKeyByValue()](./findKeyByValue.js) : findKeyByValuetakes an object and a value, then searches for the first key that maps to that value. If the value is found, it returns the corresponding key; otherwise, it returns undefined.\n\n  example: you are looking through an object (thingsAboutMe) and need the key associated with the value \"Lilac\".\n\n  ```javascript\n  const thingsAboutMe = {\n    hobby: \"Writing\",\n    business: \"The Spirit Atelier\",\n    flower: \"Lilac\",\n    colour: \"Dusty Pink\",\n  };\n\n  findKeyByValue(thingsAboutMe, \"Lilac\");\n  //returns 'flower'\n  ```\n\n- #### [flatten()](./flatten.js) : flatten() takes a single-level nested array (an array that contains arrays within it) and returns a new array with all items brought to the top level — no nesting. It only flattens one level deep, making it ideal for tidying up slightly messy data structures.\n\n  example: you manage a calendar, which includes both single bookings and group sessions (where multiple names are booked under one slot). To send out reminders, you need a flat list of all individual clients.\n\n  ```javascript\n  const bookings = [\n    \"Nicole\",\n    [\"Taryn\", \"Robyn\"],\n    \"Cassidy\",\n    [\"Kevin\", \"Devyn\", \"Priscilla\"],\n  ];\n  flatten(bookings);\n  // returns [\"Nicole\", \"Taryn\", \"Robyn\", \"Cassidy\", \"Kevin\", \"Devyn\", \"Priscilla\"]\n  ```\n\n- #### [letterPositions()](./letterPositions.js) : letterPositions() takes a string (sentence) and returns an object. Each key is a character (excluding spaces), and its value is an array of all the indices in the string where that character appears. It’s especially useful for analyzing patterns or tracking character positions in text.\n\n  example: you are writing a poem and want to track the emotional tone though frequency or cadence of vowels/consonants.\n\n  ```javascript\n  const poem = \"rustles of comfort reflected heat,\";\n\n  letterPositions(poem);\n  // returns { r: [0, 12, 21, 32], u: [1], s: [2], t: [3, 24, 34], l: [4, 27], e: [5, 22, 29, 36], o: [6, 9, 13, 16], f: [7, 23], c: [10, 26], m: [14], d: [30], h: [35], a: [37] }\n  ```\n\n- #### [map()](./map.js) :map() takes two arguments: an array of items and a callback function to apply to each item. It returns a new array, where each element is the result of calling the callback on the corresponding element from the original array.\n\n  example: you're working on more poetry and want to assign a pattern to the first letter of each word.\n\n  ```javascript\n  const poemLine = \"Ali lightly calls her exciting memory: you\";\n\n  const firstLetter = (word) => word[0];\n\n  map(poemLine, firstLetter);\n  //returns [\"a\", \"l\", \"c\", \"h\", \"e\", \"m\", \"y\"]\n  ```\n\n- #### [middle()](./middle.js) : middle() function returns the middle element(s) of an array, based on its length: If the array has 1 or 2 elements, it returns an empty array [] — because there is no meaningful \"middle.\" If the array length is odd, it returns the single middle element. If the array length is even, it returns the two middle elements.\n\n  example: you're featuring a median product as a feature in a carousel. You'd like the middle product to be featured.\n\n  ```javascript\n  const products = [\n    \"Norse Runes\",\n    \"Rune Cloth\",\n    \"Book\",\n    \"Tarot Deck\",\n    \"Journal\",\n  ];\n\n  middle(products);\n  //returns [\"Book\"]\n  ```\n\n- #### [tail()](./tail.js) : tail() function returns a new array containing all elements of the input array except the first one.\n\n  example: you have a video series on a courses platform and want the user to be able to skip the first video.\n\n  ```javascript\n  const videoSeries = [\n    \"Welcome & Course Overview\", // Intro\n    \"Lesson 1: Tarot 101\",\n    \"Lesson 2: Norse Rune Mythology\",\n    \"Lesson 3: The Planets\",\n    \"Lesson 4: The Zodiacs\",\n  ];\n  tail(videoSeries);\n  // returns [\n  //\"Lesson 1: Tarot 101\",\n  //\"Lesson 2: Norse Mythology\",\n  //\"Lesson 3: The Planets\",\n  //\"Lesson 4: The Zodiacs\",\n  //]\n  ```\n\n- #### [takeUntil()](./takeUntil.js) : takeUntil() iterates over an array and collects elements into a new array until the provided callback returns true. Once the callback returns true, the function stops adding items and returns the collected array. It does not include the item that caused the callback to return true.\n\n  example: You want to return all products that appear before the first product that contains a specific keyword — in this case, \"Runes\".\n\n  ```javascript\n  const products = [\n    \"Book\",\n    \"Tarot Deck\",\n    \"Norse Runes\",\n    \"Rune Cloth\",\n    \"Journal\",\n\n  ];,\n\n  takeUntil(products, (product) => product.includes(\"Runes\"))\n  // returns [\"Book\", \"Tarot Deck\"]\n  ```\n\n- #### [without()](./without.js) : without() returns a new array that includes all elements from the original source array except those specified in the itemsToRemove array. It does not modify the original array. It filters out all values that match anything in itemsToRemove\n\n  example: You're doing inventory for a market and want to return all items except a few which are not going to go with you.\n\n  ```javascript\n  const products = [\n    \"Book\",\n    \"Tarot Deck\",\n    \"Norse Runes\",\n    \"Rune Cloth\",\n    \"Journal\",\n\n  ];,\n\n  without(products, [\"Journal\", \"Tarot Deck\"])\n  // returns [\"Book\", \"Norse Runes\", \"Rune Cloth\"]\n  ```\n\n\\*\\* All Examples are just for fun, but hopefully provide clarity on the fuctions use.\n","readmeFilename":"README.MD"}