1

オブジェクトの配列から始めて、すべてのキーのリストとそれぞれのすべての固有の値を取得する必要があります。問題は私が事前にキーを知らないことです。キーを知っていれば、たくさんの解決法がありますが、この場合、各オブジェクトは任意の数のキーを持ち、各キーは値の配列を持ちます。以下のコードは動作しますが、非常に複雑で簡単な解決策が必要です。アンダースコアを使用してそれぞれの固有の値とキーを取得する

Made a working JSBIN here

入力:

[ 
    { 
     key_1: [ attribute_value_1, attribute_value_2, ... ], 
     key_2: [ attribute_value_3, attribute_value_4, ... ], 
    }, 
    ... 
] 

出力:

[ 
    { 
     label: key_1, 
     options: [ attribute_value_1, attribute_value_2, ... ] 
    }, 
    { 
     label: key_2, 
     options: [ attribute_value_3, attribute_value_4, ... ] 
    }, 
    ... 
] 

推奨する解決方法:

_.chain(input) 
     .map(function (attr) { 
      return _.keys(attr).map(function (key) { 
       return { 
        key: key, 
        value: attr[key] 
       }; 
      }); 
     }) 
     .flatten() 
     .groupBy('key') 
     .map(function (grouped_values, key) { 
      // value = array of { key, value } 
      return { 
       label: key, 
       options: _.chain(grouped_values) 
        .pluck('value') 
        .flatten() 
        .uniq() 
        .value() 
      }; 
     }) 
     .value(); 

答えて

2

lodash使用 - 中に_.mergeWith()を適用します配列を配置し、カスタム関数を使用して配列を結合し、一意の値を取得します。その後_.map()結果必要な形式へ:

var input = [ 
 
    { 
 
    key_1: [ "attribute_value_1", "attribute_value_2" ], 
 
    key_2: [ "attribute_value_3", "attribute_value_4" ] 
 
    }, 
 
    { 
 
    key_1: [ "attribute_value_1", "attribute_value_5" ], 
 
    key_2: [ "attribute_value_2", "attribute_value_3" ], 
 
    key_5: [ "attribute_value_2", "attribute_value_3" ] 
 
    } 
 
]; 
 

 

 
var params = [{}].concat(input).concat(function (objValue, srcValue) { // create the params to apply to mergeWith 
 
    if (_.isArray(objValue)) { 
 
    return _.union(objValue, srcValue); // merge the arrays, and get the unique values 
 
    } 
 
}); 
 

 
var result = _.map(_.mergeWith.apply(_, params), function(value, key) { // merge all objects in the array, and map the results to required format 
 
    return { 
 
    label: key, 
 
    options: value 
 
    }; 
 
    }); 
 

 
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.2/lodash.min.js"></script>

そして、あなたはES6を使用する場合は醜いparams配列をクリーンアップすることができます

const input = [ 
 
    { 
 
    key_1: [ "attribute_value_1", "attribute_value_2" ], 
 
    key_2: [ "attribute_value_3", "attribute_value_4" ] 
 
    }, 
 
    { 
 
    key_1: [ "attribute_value_1", "attribute_value_5" ], 
 
    key_2: [ "attribute_value_2", "attribute_value_3" ], 
 
    key_5: [ "attribute_value_2", "attribute_value_3" ] 
 
    } 
 
]; 
 

 
const customizer = (objValue, srcValue) => { 
 
    if (_.isArray(objValue)) { 
 
    return _.union(objValue, srcValue); // merge the arrays, and get the unique values 
 
    } 
 
}; 
 

 
const result = _.map(_.mergeWith({}, ...input, customizer), (value, key) => ({ // merge all objects in the array, and map the results to required format 
 
    label: key, 
 
    options: value 
 
})); 
 

 
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.2/lodash.min.js"></script>

+0

完璧!それはまさに私が探していたものです。ありがとう! –

+0

あなたは大歓迎です:) –

2

ますあなたがprならばアンダースコアでこれを書くことができますしかし、それをする必要はありません。

const input = [ 
 
    {key_1: [1, 2], key_2: [3, 4]}, 
 
    {key_3: [5, 6], key_2: [7, 42]} 
 
]; 
 

 
var result = [].concat(...input.map(obj => 
 
    Object.keys(obj).map(key => 
 
    ({label: key, options: obj[key]}) 
 
) 
 
)); 
 

 
console.log(result);

私はあなたが結果をuniqifyする方法をかなりよく分かりません。 [ attribute_value_1, attribute_value_2, ... ]のように、各アレイ内で一意に実行することを意味しますか?

+0

それは本当にいいですが、私が望んでいたことをしていません。コードを実行すると、 "key_2"の2つの別個のエントリが存在するので、ラベルをグループ化する別のステップが必要になります。 [] .concat(... x)は何を達成していますか?私はinput.map()を実行するだけです –

関連する問題