12

複数のカテゴリ オブジェクトを含む配列があり、各オブジェクトにitemsはアイテム オブジェクトの配列を含むプロパティがあります。プロパティ値とラベルを持つオブジェクトを使用して、各カテゴリの各アイテムを object[] にマップしたいと考えています。何らかの理由で、連結を実行できません。

var categories = [{
                name: "category1",
                items: [{
                    itemId: 1,
                    name: "Item1"
                }, {
                    itemId: 2,
                    name: "Item2"
                }]
            }, {
                name: "category2",
                items: [{
                    itemId: 3,
                    name: "Item3"
                }, {
                    itemId: 4,
                    name: "Item4"
                }]
            }];

var items = [];
for(var i = 0; i < categories.length; i++){
    items.concat($.map(categories[i].items,function(elem){
        return {value:elem.itemId, label:elem.name};
    }));
} 
console.log(items); //prints []

期待される結果

[{
   label: "Item1",
   value: "1"
},
{
   label: "Item2",
   value: "2"
},{
   label: "Item3",
   value: "3"
},{
   label: "Item4",
   value: "4"
}

何か非常に基本的なことが欠けているように感じます。$.map関数の結果をログに記録したところ、 []. 誰でも問題を理解できますか?

JSFiddle: http://jsfiddle.net/vymJv/

4

6 に答える 6

25

ストレート Javascript を使用する別の方法:

var x = categories.map(function(val) {
  return val.items;
}).reduce(function(pre, cur) {
   return pre.concat(cur);
}).map(function(e,i) {
  return {label:e.name,value:e.itemId};
});

出力:x = [{label: "Item1", value: 1}, {label: "Item2", value: 2}, …]

于 2015-07-29T18:09:45.090 に答える
9

concat() メソッドは、2 つ以上の配列を結合するために使用されます。

このメソッドは既存の配列を変更しませんが、結合された配列の値を含む新しい配列を返します。

http://jsfiddle.net/vymJv/1/

for(var i = 0; i < categories.length; i++){
    items = items.concat($.map(categories[i].items, function(elem) {
        return {value: elem.itemId, label: elem.name};
    }));
}
于 2013-06-12T15:25:32.777 に答える
4
  const items = categories
          .map(category => category.items)
          .reduce((prev, current) => [...prev, ...current])
          .map((e, i) => ({ label: e.name, value: e.itemId }));
于 2020-03-12T18:13:23.713 に答える
3

このコードは、関数型プログラミングのアプローチを使用してタスクを解決します。

var items = [].concat.apply([], categories.map(cat =>
  cat.items.map(elem => ({ value:elem.itemId, label:elem.name })))
)

説明: Function.prototype.apply()には構文がfun.apply(thisArg, [argsArray])あり、配列内の関数にパラメーターを提供できます。Array.prototype.concat()は、任意の量のパラメーターを 1 つの配列に結合します。ここで と書くArray.prototype.concat.apply([], [category1Items, ..., categoryNItems])と、実際には に等しくなり[].concat(category1Items, ..., categoryNItems)、すべてのパラメータが連結されます。で置き換えて短くすることもできArray.prototype.concatます[].concat。それ以外の場合は、標準のマッピングを使用して作業を完了します。

わかりやすくするために、コードをもう少し分割することもできます。

function getItem(elem){
  return {value:elem.itemId, label:elem.name};
}

function getCategoryItems(cat) {
  return cat.items.map(getItem);
}

function flatten(arr) {
  return Array.prototype.concat.apply([], arr);
}

var items = flatten(categories.map(getCategoryItems));
于 2016-11-19T12:43:46.073 に答える
3

各サブ配列を反復処理し、各値を新しい配列にダンプすることですべての配列を連結するconcatAllを作成することで、配列プロトタイプを拡張できます。

Array.prototype.concatAll = function() {
  var results = [];
  this.forEach(function(subArray) {
    subArray.forEach(function(subArrayValue) {
      results.push(subArrayValue);
    });
  });
  return results;
};

次に、次の方法で目的の結果を得ることができます。

let items = categories.map(function(category) {
  return category.items.map(function(item) {
    return {label: item.name, value: item.itemId};
  });
}).concatAll();

各カテゴリをアイテムの配列に変換してアイテムを取得します。2 つのカテゴリがあるため、2 つの項目の配列になります。最終結果にconcatAllを適用することで、これら 2 つの項目の配列を平坦化し、目的の出力を取得します。

于 2016-03-26T22:38:13.780 に答える