Эквивалент Underscore _.pluck в чистом JavaScript

Я пытаюсь воссоздать функцию подделки Underscore с использованием чистого JS. Тем не менее, я продолжаю получать массив неопределенных значений, а не фактические значения из свойств объектов в массиве.

Проверка другого потока here Я обнаружил, что вы можете воспроизвести его в jQuery со следующим кодом...

$.pluck = function(arr, key) { 
    return $.map(arr, function(e) { return e[key]; }) 
}

... однако мне трудно воспроизвести это в чистом JS. Я попробовал следующее, но это просто возвращает массив неопределенных значений для меня.

var pluck = function(arr,key){
  var newArr = [];
  for (var i = 0, x = arr.length; i < x; i++){
    if (arr[i].hasOwnProperty(key)){
      newArr.push(arr[i].key)
    }
  }
  return newArr;
}

Итак, целью будет следующее: кроме использования подчеркивания _.pluck просто используйте имя функции JS, например. var pluck = function (arr, key) {...}

var Tuts = [{name : 'NetTuts', niche : 'Web Development'}, {name : 'WPTuts', niche : 'WordPress'}, {name : 'PSDTuts', niche : 'PhotoShop'}, {name : 'AeTuts', niche : 'After Effects'}];
var niches = _.pluck(Tuts, 'niche');

console.log(niches);

// ["Web Development", "WordPress", "PhotoShop", "After Effects"]

Может ли кто-нибудь направить меня в правильном направлении?

Ответы

Ответ 1

Вы можете сделать это с помощью родного JavaScript .map():

Array.prototype.pluck = function(key) {
  return this.map(function(object) { return object[key]; });
};

edit — изменение встроенных объектов-прототипов должно выполняться с осторожностью; лучший способ добавить функцию (если вы в порядке с идеей сделать это вообще) будет с Object.defineProperty, чтобы его можно было сделать неперечислимым:

Object.defineProperty(Array.prototype, "pluck", {
    value: function(key) {
        return this.map(function(object) { return object[key]; });
    }
});

Ответ 2

Ты так близко. Вам нужно изменить:

newArr.push(arr[i].key);

в

newArr.push(arr[i][key]);

Рассмотрим это:

var obj = { myKey: 'my Value', theKey: 'another value' };
var theKey = 'myKey';

alert(obj.theKey); // another value
alert(obj[theKey]); // my Value
// You can also send in strings here:
alert(obj['theKey']); // another value

Надеюсь, вы поняли мою мысль.

Ответ 3

В ES5:

function pluck(array, key) {
  return array.map(function(obj) {
    return obj[key];
  });
}

В ES6:

function pluck(array, key) {
  return array.map(o => o[key]);
}

Ответ 4

Здесь рабочее решение

function pluck(array,key){
  var a = [],
     i1 = -1, i2 = array.length,
      o ;

    while(++i1 < i2)
    {
        o = array[i1] ; // you have to use the bracket operator here
        if(o.hasOwnProperty(key)) a[a.length] = o[key] ;
    }
  return a ;
}

Я не очень сильно менял. Причина отказа вашего кода в том, что вы использовали оператор точки .key для доступа к именованному свойству элементов массива вместо оператора скобки [key]. При использовании ссылки в качестве ключа вам необходимо использовать оператор скобки.

Ответ 5

Как насчет сокращения:

$.pluck = function(arr, key) { 
    return arr.reduce(function(p, v) { 
      return p.concat(v[key]); 
    }, []); 
}

var people = [
  { name: 'James', age: 26 }, 
  { name: 'Fred', age: 56 }
];

$.pluck(people, 'age');
=> [26, 56]

$.pluck(people, 'name');
=> ['James', 'Fred']

Ответ 6

var array = {
name: ["Pedro", "João", "Francisco", "Diogo"],
ID: [1,2,3,4]
};
console.log(pluck(array,'name'));

function pluck(array, key) {
   return (array[key]);
};

JSFiddle

Вы можете использовать эту функцию, щелкнуть в JSFiddle, чтобы увидеть пример!:)