webentwicklung-frage-antwort-db.com.de

Entsprechung von Underscore _.pluck in reinem JavaScript

Ich versuche die Underscore-Zupffunktion mit reinem JS neu zu erstellen. Ich bekomme jedoch immer wieder ein Array von undefineds, das zurückgegeben wird, anstelle der tatsächlichen Werte aus den Eigenschaften der Objekte in einem Array. 

Beim Prüfen eines anderen Threads hier habe ich festgestellt, dass Sie ihn mit dem folgenden Code in jQuery reproduzieren könnten ...

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

... aber ich habe Schwierigkeiten, dies nur in reinem JS zu reproduzieren. Ich habe folgendes ausprobiert, dies liefert jedoch nur ein Array von undefineds für mich. 

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;
}

Das Ziel wäre also Folgendes: Anstatt den Unterstrich _.pluck zu verwenden, verwenden Sie einfach einen JS-Funktionsnamen, z. var pluck = Funktion (Arr, Schlüssel) {...}

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"]

Könnte mich jemand in die richtige Richtung lenken?

18
wesleysmyth

In ES5:

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

In ES6: 

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

Sie können dies mit dem nativen JavaScript .map() tun:

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

edit - Das Ändern von eingebauten Prototypobjekten sollte mit Vorsicht erfolgen. Eine bessere Möglichkeit, die Funktion hinzuzufügen (sollten Sie mit der Idee, dies im Allgemeinen zu tun, OK sein), wäre mit Object.defineProperty so, dass sie nicht mehr aufgezählt werden kann:

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

Du bist so nah. Du musst dich ändern:

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

zu:

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

Bedenken Sie:

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

Ich hoffe, du bekommst meinen Punkt.

7
andlrc

Wie wäre es mit einer Reduzierung:

$.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']
0
Jivings

Hier ist eine Arbeitslösung

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 ;
}

Ich habe mich nicht wirklich so sehr verändert. Der Grund für das Fehlschlagen des Codes liegt darin, dass Sie mit dem Punktoperator .key auf die benannte Eigenschaft der Array-Elemente anstelle des Klammeroperators [key] zugegriffen haben. Wenn Sie eine Referenz als Schlüssel verwenden, müssen Sie den Klammeroperator verwenden.

0
FK82