395 Stimmen

Führen Sie .join auf Wert in Array von Objekten aus

Wenn ich ein Array von Zeichenfolgen habe, kann ich die .join() Methode verwenden, um eine einzelne Zeichenfolge zu erhalten, wobei jedes Element durch Kommas getrennt ist, wie folgt:

["Joe", "Kevin", "Peter"].join(", ") // => "Joe, Kevin, Peter"

Ich habe ein Array von Objekten und möchte eine ähnliche Operation auf einem darin enthaltenen Wert durchführen; also aus

[
  {name: "Joe", age: 22},
  {name: "Kevin", age: 24},
  {name: "Peter", age: 21}
]

führen Sie die join Methode nur auf dem name Attribut aus, um das gleiche Ergebnis wie zuvor zu erzielen.

Derzeit habe ich die folgende Funktion:

function joinObj(a, attr){
  var out = [];

  for (var i = 0; i < a.length; i++){
    out.push(a[i][attr]);
  }

  return out.join(", ");
}

An diesem Code ist nichts auszusetzen, er funktioniert, aber plötzlich bin ich von einer einfachen, prägnanten Codezeile zu einer sehr imperativen Funktion übergegangen. Gibt es einen prägnanteren, idealerweise funktionaleren Weg, um dies zu schreiben?

687voto

Benjamin Gruenbaum Punkte 259076

Wenn Sie Objekte auf etwas (in diesem Fall eine Eigenschaft) abbilden möchten, denke ich Array.prototype.map ist das, wonach Sie suchen, wenn Sie funktional programmieren möchten.

(fiddle)

Wenn Sie ältere Browser unterstützen möchten, die nicht ES5-konform sind, können Sie es shimmen (es gibt ein Polyfill auf der oben genannten MDN-Seite). Eine andere Alternative wäre die Verwendung der pluck-Methode von underscorejs:

var users = [
      {name: "Joe", age: 22},
      {name: "Kevin", age: 24},
      {name: "Peter", age: 21}
    ];
var result = _.pluck(users,'name').join(",")

90voto

basilikum Punkte 9984

Sie können immer die toString Methode Ihrer Objekte überschreiben:

    var arr = [
        {name: "Joe", age: 22, toString: function(){return this.name;}},
        {name: "Kevin", age: 24, toString: function(){return this.name;}},
        {name: "Peter", age: 21, toString: function(){return this.name;}}
    ];

    var result = arr.join(", ");
    console.log(result);

34voto

ariel Punkte 14427

On node or ES6+:

const users = [{
    name: "Joe",
    age: 22
  },
  {
    name: "Kevin",
    age: 24
  },
  {
    name: "Peter",
    age: 21
  }
];

console.log(
  users.map(u => u.name).join(', ')
);

23voto

jackweirdy Punkte 5502

Ich bin auch auf die Verwendung der reduce-Methode gestoßen, so sieht es aus:

console.log(
    [
        {name: "Joe", age: 22},
        {name: "Kevin", age: 24},
        {name: "Peter", age: 21}
    ]
    .reduce(function (a, b) {
        return (a.name || a) + ", " + b.name}
    )
)

Das (a.name || a) ist, damit das erste Element korrekt behandelt wird, aber der Rest (wo a eine Zeichenfolge ist und also a.name undefiniert ist) nicht als Objekt behandelt wird.

Änderung: Ich habe es jetzt weiter refaktorisiert zu diesem:

x.reduce(function(a, b) {return a + ["", ", "][+!!a.length] + b.name;}, "");

was ich für sauberer halte, da a immer eine Zeichenfolge ist, b immer ein Objekt ist (aufgrund der Verwendung des optionalen initialValue-Parameters in reduce)

Änderung 6 Monate später: Oh, was habe ich mir dabei gedacht. "sauberer". Ich habe die Code-Götter verärgert.

12voto

Prajwal Panta Punkte 121
const lists  = [
  {name: "Joe", age: 22},
  {name: "Kevin", age: 24},
  {name: "Peter", age: 21}
]

const joinedStr = lists.map((list) => list.name).join(" ")

console.log('joined',joinedStr)

Dies sollte funktionieren, da map ein Array von Zeichenketten zurückgibt und diese dann verknüpft werden können.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X