locutus
Version:
Locutus other languages' standard libraries to JavaScript for fun and educational purposes
53 lines (52 loc) • 2.15 kB
JavaScript
import { isObjectLike } from "../_helpers/_phpTypes.js";
function mergeInto(result, source) {
let numericIdx = Object.keys(result).filter((key) => parseInt(key, 10) + '' === key + '').length;
// Helper to check if a key is numeric (PHP integer-indexed)
const isNumericKey = function (key) {
return parseInt(key, 10) + '' === key + '';
};
// Helper to check if value is a plain object (not array)
const isPlainObject = function (val) {
return isObjectLike(val) && !Array.isArray(val);
};
for (const [key, sourceValue] of Object.entries(source)) {
if (isNumericKey(key)) {
result[numericIdx++] = sourceValue;
}
else if (key in result) {
const resultValue = result[key];
if (isPlainObject(resultValue) && isPlainObject(sourceValue)) {
result[key] = array_merge_recursive(resultValue, sourceValue);
}
else if (Array.isArray(resultValue)) {
resultValue.push(sourceValue);
}
else {
result[key] = [resultValue, sourceValue];
}
}
else {
result[key] = sourceValue;
}
}
}
export function array_merge_recursive(...arrays) {
// discuss at: https://locutus.io/php/array_merge_recursive/
// original by: Subhasis Deb
// input by: Brett Zamir (https://brett-zamir.me)
// bugfixed by: Kevin van Zonneveld (https://kvz.io)
// reimplemented by: Kevin van Zonneveld (https://kvz.io)
// note 1: Numeric keys are renumbered starting from 0, string keys are preserved
// example 1: var $arr1 = {'color': {'favorite': 'red'}, 0: 5}
// example 1: var $arr2 = {0: 10, 'color': {'favorite': 'green', 0: 'blue'}}
// example 1: array_merge_recursive($arr1, $arr2)
// returns 1: {'color': {'favorite': ['red', 'green'], 0: 'blue'}, 0: 5, 1: 10}
if (arrays.length === 0) {
return {};
}
const result = {};
for (const array of arrays) {
mergeInto(result, array);
}
return result;
}