jQuery中是否有与PHP的array_column()等效的函数?

16
什么是jQuery中等价于PHP的array_column()函数? 我需要在不使用循环的情况下获取数组中的数据,与PHP中的方法相同。

https://dev59.com/Imgu5IYBdhLWcg3wnoaC - Hanky Panky
5
无论是本地方法还是其他任何方法,你使用的任何内容都会循环数组。 - charlietfl
https://dev59.com/z2sz5IYBdhLWcg3wg4Gv - zavg
在jQuery中不可能实现(即使没有循环,无论是对肉眼可见还是不可见) - CSᵠ
6个回答

40

你可以使用.map()来完成。想象一下从数据库中获取行的操作。

使用箭头函数

要创建一个可重用的arrayColumn(array, column)函数:

const array = [
    {id: 1, name: 'foo'},
    {id: 2, name: 'bar'},
];
const arrayColumn = (array, column) => {
    return array.map(item => item[column]);
};
const names = arrayColumn(array, 'name');
console.log(names);

或者您可以直接使用.map

const array = [
    {id: 1, name: 'foo'},
    {id: 2, name: 'bar'},
];
const names = array.map(item => item.name);
console.log(names);

ES6(2015)之前

var array = [
    {id: 1, name: 'foo'},
    {id: 2, name: 'bar'},
];
function arrayColumn(array, columnName) {
    return array.map(function(value,index) {
        return value[columnName];
    })
}
var names = arrayColumn(array, 'name');
console.log(names);


10

Fabian的答案的简短版本,使用箭头符号:

let array = [
    {
        id: 1,
        name: 'foo'
    },
    {
        id: 2,
        name: 'bar'
    },
];

let names = array.map( el => el.name );

0

我使用这个工具来构建一个对象,类似于 PHP 关联数组。通过选择源数组的 .id,将该 id 构建为新数组的索引,并包含旧源数组相同的内容。

var categoriesById={};

for(item in cacheObject.Categories){
categoriesById[cacheObject.Categories[item].id]=cacheObject.Categories[item];
}

0
在这篇文章的底部是我实现的PHP array_column() 的JavaScript版本。不需要jQuery。
使用示例:
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'}
//    }

实现:
/**
 * Source: https://dev59.com/C18d5IYBdhLWcg3wpzr4#33841999
 *
 * 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():
 * <ul>
 *     <li>If <code>indexKey</code> 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.
 *
 *     <li>Associative arrays (dictionaries) in PHP are ordered, JavaScript objects are not (https://dev59.com/jW035IYBdhLWcg3wQtsg#5525820.
 *     Do not make assumptions on the ordering of the keys in JavaScript objects.
 *
 *     <li>If the value of an element at <code>inputKey</code> is not a string, the result of this function and the PHP function
 *     doesn't make much sense. For example, in PHP,
 *     <code>
 *          $records = array(
 *              array('id' => true, 'last_name' => 'Doe')
 *          );
 *          array_column($records, 'last_name', 'id');
 *     </code>
 *     gives <code>Array([1] => Doe)</code>, or maybe <code>Array([0] => Doe)</code> due to a bug ({@link https://bugs.php.net/bug.php?id=68553}). But, in JavaScript,
 *     <code>
 *          var records = [
 *              {id: true, last_name: 'Doe'},
 *          ];
 *          arrayColumn(records, 'last_name', 'id');
 *     </code>
 *     gives <code>{true: "Doe"}</code>. Therefore, it is strongly advised to make sure that the value at <code>indexKey</code> of
 *     each input element is a string.
 * </ul>
 *
 * @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 <code>null</code>.
 * @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 <code>null</code>.
 * @returns {Array|Object}                      If <code>indexKey</code> is <code>null</code>, this function returns an array which is parallel
 *                                              to the input array. For each element <code>elem</code> in the input array, the element in the
 *                                              output array would be <code>elem[columnKey]</code>, or just <code>elem</code> if <code>columnKey</code>
 *                                              is <code>null</code>.
 *                                              If <code>indexKey</code> is <b>not</b> <code>null</code>, this function returns an object.
 *                                              For each element <code>elem</code> in the input array, the output object would contain an
 *                                              element <code>elem[columnKey]</code>, or just <code>elem</code> if <code>columnKey</code>
 *                                              is <code>null</code>, at the key <code>elem[indexKey]</code>. If the value of <code>elem[indexKey]</code>
 *                                              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);
}

为什么默认是排序的呢?例如,如果我改变给定数组中的顺序,那么结果应该与给定的顺序相同。但它总是按键排序。 - Deep Kakkar
@DeepKakkar 你说的按键排序是什么意思?能给个简单的例子吗? - Pang

0
var data = [];
data.push({col1: 1, col2: 2});
data.push({col1: 3, col2: 4});
data.push({col1: 5, col2: 6});

Array.prototype.getColumn = function(name) {
    return this.map(function(el) {
       // gets corresponding 'column'
       if (el.hasOwnProperty(name)) return el[name];
       // removes undefined values
    }).filter(function(el) { return typeof el != 'undefined'; }); 
};

console.log(data.getColumn('col1'));

结果

Array[3]
0: 1
1: 3
2: 5

可以通过获取数组的第一个元素并检查其是否具有相应的键来跳过.filter部分。但是,有些行可能根本没有该键,而其他行可能具有该键。

-5
你是指像这样吗:
var a = {};
a['alfa'] = 0;
a['beta'] = 1;

alert(a['alfa']);

2
不回答问题。 - CSᵠ
1
请仔细阅读问题。 - aBhijit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接