What is the equivalent to PHP\'s array_column()
in jQuery? I need the data inside the array without looping, in the same way as in PHP.
At the bottom of this post is my JavaScript implementation of PHP's array_column(). No jQuery needed.
Example usage:
var records = [
{id: 2135, first_name: 'John', last_name: 'Doe'},
{id: 3245, first_name: 'Sally', last_name: 'Smith'},
{id: 5342, first_name: 'Jane', last_name: 'Jones'},
{id: 5623, first_name: 'Peter', last_name: 'Doe'}
];
var first_names = arrayColumn(records, 'first_name');
// => ["John", "Sally", "Jane", "Peter"]
var last_names = arrayColumn(records, 'last_name', 'id');
// => {2135: "Doe", 3245: "Smith", 5342: "Jones", 5623: "Doe"}
var persons = arrayColumn(records, null, 'id');
// => {
// 2135: {id: 2135, first_name: 'John', last_name: 'Doe'},
// 3245: {id: 3245, first_name: 'Sally', last_name: 'Smith'},
// 5342: {id: 5342, first_name: 'Jane', last_name: 'Jones'},
// 5623: {id: 5623, first_name: 'Peter', last_name: 'Doe'}
// }
Implementation:
/**
* Source: http://stackoverflow.com/a/33841999/1402846
*
* This function is (almost) equivalent to array_column() in PHP (http://php.net/manual/function.array-column.php).
*
* Differences between this function and PHP's array_column():
*
* - If
indexKey
is not found in an element of the input array, the behaviour of this function is undefined.
* In PHP's array_column(), the element will be put into the end of the array. It is possible in PHP because PHP does not
* distinguish between arrays and dictionaries, but it is not possible in JavaScript because Arrays and Objects are different.
*
* - Associative arrays (dictionaries) in PHP are ordered, JavaScript objects are not (http://stackoverflow.com/a/5525820/14028460.
* Do not make assumptions on the ordering of the keys in JavaScript objects.
*
*
- If the value of an element at
inputKey
is not a string, the result of this function and the PHP function
* doesn't make much sense. For example, in PHP,
*
* $records = array(
* array('id' => true, 'last_name' => 'Doe')
* );
* array_column($records, 'last_name', 'id');
*
* gives Array([1] => Doe)
, or maybe Array([0] => Doe)
due to a bug ({@link https://bugs.php.net/bug.php?id=68553}). But, in JavaScript,
*
* var records = [
* {id: true, last_name: 'Doe'},
* ];
* arrayColumn(records, 'last_name', 'id');
*
* gives {true: "Doe"}
. Therefore, it is strongly advised to make sure that the value at indexKey
of
* each input element is a string.
*
*
* @param {Array|Object} inputArray The input array, it must either contain objects only or arrays only.
* If it is an object instead of an array, it would be converted to an array first.
* @param {int|string|null} columnKey If the input array contains objects, this parameter is the key in each object.
* If the input array contains arrays, this parameter is the index in each array.
* If the key or index is not valid, this element is skipped.
* This parameter may also be null
.
* @param {int|string|null} [indexKey=null] If the input array contains objects, this parameter must be a valid key in each object.
* If the input array contains arrays, this parameter must be a valid index in each array.
* If it is not a valid key or index, the behaviour is undefined.
* This parameter may also be null
.
* @returns {Array|Object} If indexKey
is null
, this function returns an array which is parallel
* to the input array. For each element elem
in the input array, the element in the
* output array would be elem[columnKey]
, or just elem
if columnKey
* is null
.
* If indexKey
is not null
, this function returns an object.
* For each element elem
in the input array, the output object would contain an
* element elem[columnKey]
, or just elem
if columnKey
* is null
, at the key elem[indexKey]
. If the value of elem[indexKey]
* of some elements in the input array are duplicated, the element in the return object would
* correspond to the element nearest to the end of the input array.
* @example
* var records = [
* {id: 2135, first_name: 'John', last_name: 'Doe'},
* {id: 3245, first_name: 'Sally', last_name: 'Smith'},
* {id: 5342, first_name: 'Jane', last_name: 'Jones'},
* {id: 5623, first_name: 'Peter', last_name: 'Doe'}
* ];
* var first_names = arrayColumn(records, 'first_name');
* >> ["John", "Sally", "Jane", "Peter"]
* var last_names = arrayColumn(records, 'last_name', 'id');
* >> {2135: "Doe", 3245: "Smith", 5342: "Jones", 5623: "Doe"}
* var persons = arrayColumn(records, null, 'id');
* >> {
* 2135: {id: 2135, first_name: 'John', last_name: 'Doe'},
* 3245: {id: 3245, first_name: 'Sally', last_name: 'Smith'},
* 5342: {id: 5342, first_name: 'Jane', last_name: 'Jones'},
* 5623: {id: 5623, first_name: 'Peter', last_name: 'Doe'}
* }
*/
function arrayColumn(inputArray, columnKey, indexKey)
{
function isArray(inputValue)
{
return Object.prototype.toString.call(inputValue) === '[object Array]';
}
// If input array is an object instead of an array,
// convert it to an array.
if(!isArray(inputArray))
{
var newArray = [];
for(var key in inputArray)
{
if(!inputArray.hasOwnProperty(key))
{
continue;
}
newArray.push(inputArray[key]);
}
inputArray = newArray;
}
// Process the input array.
var isReturnArray = (typeof indexKey === 'undefined' || indexKey === null);
var outputArray = [];
var outputObject = {};
for(var inputIndex = 0; inputIndex < inputArray.length; inputIndex++)
{
var inputElement = inputArray[inputIndex];
var outputElement;
if(columnKey === null)
{
outputElement = inputElement;
}
else
{
if(isArray(inputElement))
{
if(columnKey < 0 || columnKey >= inputElement.length)
{
continue;
}
}
else
{
if(!inputElement.hasOwnProperty(columnKey))
{
continue;
}
}
outputElement = inputElement[columnKey];
}
if(isReturnArray)
{
outputArray.push(outputElement);
}
else
{
outputObject[inputElement[indexKey]] = outputElement;
}
}
return (isReturnArray ? outputArray : outputObject);
}