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>

如果你使用,你可以清理醜陋params陣列ES6:

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

你如果你是公關的話,可以在Underscore中寫下儘管如此,但沒有迫切需要這樣做。

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」將有兩個單獨的條目,因此必須有另一個按標籤對數組進行分組的步驟。 [] .concat(... x)實現了什麼?我只需要運行input.map() –

相關問題