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() –

相关问题