使用下划线获取所有键和每个键的惟一值列表

Using underscore to get all keys and list of unique values for each

本文关键字:列表 下划线 获取      更新时间:2023-09-26

从一个对象数组开始,我需要得到一个包含所有键和每个键的惟一值的列表。问题是我事先不知道钥匙。如果知道键,有很多解决方案,但在这种情况下,每个对象可以有任意数量的键,每个键都有一个值数组。下面的代码可以工作,但它相当复杂,必须有一个更简单的解决方案。

在这里创建了一个工作的JSBIN

输入:

[
    {
        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();

Using lodash -将_.mergeWith()应用于输入数组,并使用customizer函数将数组组合并获得唯一值。然后_.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>

如果您喜欢的话,可以用下划线来写,但是没有必要这么做。

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);

我不太确定你想如何统一结果。您的意思是您希望在每个数组(如[ attribute_value_1, attribute_value_2, ... ])中运行唯一的吗?