Differences from Laravel
@tolki/arr, @tolki/obj and @tolki/data follow Laravel's Arr class and data_* helpers wherever JavaScript can hold the same data. This page lists the places where they cannot, or choose not to. For the rules they keep on purpose, see PHP Semantics.
Return values instead of references
Laravel's Arr::set(), forget(), push() and pull() take the array by reference and change it. JavaScript cannot pass a variable that way, so these functions return the result and leave what you passed in unchanged. Assign the result to keep it.
setreturns the array or object with the value written.forgetreturns it with the path removed.pushreturns it with the values appended to the array at the path.pullreturns{ value, data }: the item taken out, and the data without it.
import { forget, pull, push, set } from "@tolki/arr";
const grid = [["a", "b"], ["c"]];
set(grid, "0.1", "z");
// => [["a", "z"], ["c"]]
forget(grid, "0.1");
// => [["a"], ["c"]]
push(grid, "1", "d");
// => [["a", "b"], ["c", "d"]]
pull(grid, "0.0");
// => { value: "a", data: [["b"], ["c"]] }
grid;
// => [["a", "b"], ["c"]]import { forget, pull, push, set } from "@tolki/obj";
const desk = { price: { amount: 100, tax: 7 }, tags: ["a"] };
set(desk, "price.amount", 200);
// => { price: { amount: 200, tax: 7 }, tags: ["a"] }
forget(desk, "price.tax");
// => { price: { amount: 100 }, tags: ["a"] }
push(desk, "tags", "b");
// => { price: { amount: 100, tax: 7 }, tags: ["a", "b"] }
pull(desk, "price.tax");
// => { value: 7, data: { price: { amount: 100 }, tags: ["a"] } }
desk;
// => { price: { amount: 100, tax: 7 }, tags: ["a"] }import { dataForget, dataPull, dataPush, dataSet } from "@tolki/data";
const desk = { price: { amount: 100, tax: 7 }, tags: ["a"] };
dataSet(desk, "price.amount", 200);
// => { price: { amount: 200, tax: 7 }, tags: ["a"] }
dataForget(desk, "price.tax");
// => { price: { amount: 100 }, tags: ["a"] }
dataPush(desk, "tags", "b");
// => { price: { amount: 100, tax: 7 }, tags: ["a", "b"] }
dataPull(desk, "price.tax");
// => { value: 7, data: { price: { amount: 100 }, tags: ["a"] } }
desk;
// => { price: { amount: 100, tax: 7 }, tags: ["a"] }shift, pop, splice and unshift are different. Laravel gets them from Collection, which changes itself, and the functions keep that: they change the array or object you pass and return what came out (or the changed value, for unshift).
import { pop, shift, splice, unshift } from "@tolki/arr";
const queue = [1, 2, 3, 4, 5];
shift(queue);
// => 1
pop(queue);
// => 5
splice(queue, 1, 1);
// => [3]
unshift(queue, 0);
// => [0, 2, 4]
queue;
// => [0, 2, 4]import { pop, shift } from "@tolki/obj";
const stock = { a: 1, b: 2, c: 3 };
shift(stock);
// => 1
pop(stock);
// => 3
stock;
// => { b: 2 }import { dataPop, dataShift } from "@tolki/data";
const queue = [1, 2, 3];
dataShift(queue);
// => 1
dataPop(queue);
// => 3
queue;
// => [2]Behaviour differences
floataccepts a whole number such as1, where Laravel'sArr::float()throws, because PHP'sis_float()rejects an integer. JavaScript has one number type.get,hasand the other path readers take*,{first}and{last}as plain key names, where Laravel'sdata_get()expands them.pluckdoes read a*.- On a list,
where,rejectandwhereNotNullreturn the kept values as a new array numbered from 0, where Laravel keeps each value's original key. An object keeps its keys. - The functions Laravel takes from
Collectiongive the same list result:filter,intersectAssoc,intersectByKeys,diffKeys,reverse,skipUntilandskipWhilereturn a list numbered from 0 where Laravel keeps each value's original key.chunk,chunkByandchunkWhilerenumber the values inside each chunk, where Laravel keeps their keys.diff,diffAssoc,intersectandslicereturn a fresh list in the same way.@tolki/objkeeps the keys of an object. dataGetreads a literal key that contains a dot before it splits the path, sodataGet({ "a.b": 1, a: { b: 2 } }, "a.b")is1, where Laravel'sdata_get()is2. When the literal key is the only one,dataGetstill finds it anddata_get()returns the default.getin@tolki/objdoes the same.- A plain object lists integer-like keys first, in ascending order, whatever order you wrote them. Laravel's arrays keep insertion order. A
Mapkeeps insertion order, so pass one when the order matters. - With a final glue and a single item,
joinreturns that item cast to a string, where Laravel returns the item as it is:1stays the number1.
import { chunk, filter, float, intersectAssoc, join, where } from "@tolki/arr";
import { dataGet } from "@tolki/data";
import { divide, filter as filterObject, get, reject } from "@tolki/obj";
float([{ price: 1 }], "0.price");
// => 1
get({ a: { n: 1 }, b: { n: 2 } }, "*.n");
// => null
where(
["100", "200", "300", "400"],
(value) => value === "200" || value === "400",
);
// => ["200", "400"]
reject({ a: 1, b: 2, c: 3 }, (value) => value > 1);
// => { a: 1 }
filter([1, 2, 3], (value) => value !== 2);
// => [1, 3]
filterObject({ 0: 1, 1: 2, 2: 3 }, (value) => value !== 2);
// => { 0: 1, 2: 3 }
intersectAssoc(["a", "b", "c"], ["a", "x", "c"]);
// => ["a", "c"]
chunk([1, 2, 3, 4, 5], 2);
// => [[1, 2], [3, 4], [5]]
dataGet({ "a.b": 1, a: { b: 2 } }, "a.b");
// => 1
dataGet({ "a.b": 1 }, "a.b", "miss");
// => 1
get({ "a.b": 1, a: { b: 2 } }, "a.b");
// => 1
divide({ x: 1, 0: 2 });
// => [[0, "x"], [2, 1]]
divide(
new Map([
["x", 1],
[0, 2],
]),
);
// => [["x", 0], [1, 2]]
join([1], ", ", " and ");
// => "1"Not ported
These Laravel helpers have no function in the packages.
Arr::isAssoc()andArr::isList(): in none of the three.Array.isArray()tells a list from an object.data_fill(), and the globalhead()andlast()helpers.firstandlastfrom the packages areArr::first()andArr::last().accessible,arrayableandwrapin@tolki/data.@tolki/arrand@tolki/objhave them.
import * as arr from "@tolki/arr";
import * as data from "@tolki/data";
import * as obj from "@tolki/obj";
"isList" in arr || "isAssoc" in obj || "dataFill" in data;
// => false
"dataAccessible" in data || "dataArrayable" in data || "dataWrap" in data;
// => falseRenamed
Arr::array()isarrayItemin@tolki/arr,objectItemin@tolki/objanddataItemin@tolki/data.arrayis too generic a name to export.Arr::arrayable()isarrayablein@tolki/arrandobjectifiablein@tolki/obj.data_get(),data_set()anddata_forget()aredataGet,dataSetanddataForget. Every other function in@tolki/datatakes the samedataprefix, soArr::pluck()isdataPluck.
import { arrayItem } from "@tolki/arr";
arrayItem([{ tags: ["a"] }], "0.tags");
// => ["a"]import { objectItem } from "@tolki/obj";
objectItem({ desk: { price: 100 } }, "desk");
// => { price: 100 }import { dataItem } from "@tolki/data";
dataItem([{ tags: ["a"] }], "0.tags");
// => ["a"]
dataItem({ desk: { price: 100 } }, "desk");
// => { price: 100 }JavaScript-only additions
- Functions Laravel has on
Collectionrather than onArr. All three packages exportchunk,chunkBy,chunkWhile,combine,contains,containsStrict, thediffandintersectfamilies,filter,flip,keys,pad,pop,replace,replaceRecursive,reverse,shift,skipUntil,skipWhile,slice,splice,takeUntil,takeWhile,union,unshiftandvalues.@tolki/dataalso hasdataCount,dataSearch,dataBeforeanddataAfter. flattenDotin@tolki/objflattens likedotbut drops an empty nested object or array, wheredotkeeps it as a value, as Laravel'sArr::dot()does.dataUndot(data, true)builds a list from paths made of whole numbers such as"0.1", asundotfrom@tolki/arralways does. It throws aTypeErrorfor any other path.- Every function that takes a dot path reads and writes a
Mapat any depth as Laravel reads a nested array, anddotandflattenDotwalk one the same way. A write keeps theMapaMapand keeps its key order. Helpers that recurse through values, such asflatten,sortRecursiveandreplaceRecursive, do not walk into a nestedMap. When the whole data is aMap, a path function that writes, such asset,forgetorpush, returns a plain object. @tolki/datareads aSetand a generator as a list.
import {
dataAfter,
dataBefore,
dataCount,
dataFrom,
dataGet,
dataSearch,
dataUndot,
} from "@tolki/data";
import { dot, flatten, flattenDot, set } from "@tolki/obj";
dataCount({ a: 1, b: 2 });
// => 2
dataSearch([1, 2, 3], 2);
// => 1
dataBefore([1, 2, 3], 3);
// => 2
dataAfter([1, 2, 3], 1);
// => 2
dot({ a: {}, b: { c: 1 } });
// => { a: {}, "b.c": 1 }
flattenDot({ a: {}, b: { c: 1 } });
// => { "b.c": 1 }
dataUndot({ "0.0": "x", 0.1: "y" }, true);
// => [["x", "y"]]
dataFrom(new Set([1, 2]));
// => [1, 2]
dataGet(new Map([["a", { b: 1 }]]), "a.b");
// => 1
set(
{
m: new Map([
[2, "c"],
[0, "a"],
]),
},
"m.1",
"b",
);
// => { m: new Map([[2, "c"], [0, "a"], [1, "b"]]) }
flatten({ m: new Map([["a", 1]]) });
// => [new Map([["a", 1]])]