【问题标题】:Using underscore to get all keys and list of unique values for each使用下划线获取每个键的所有键和唯一值列表
【发布时间】:2017-02-09 07:58:34
【问题描述】:

从对象数组开始,我需要获取所有键的列表以及每个键的所有唯一值。问题是我事先不知道密钥。如果您知道键,则有很多解决方案,但在这种情况下,每个对象都可以有任意数量的键,并且每个键都有一个值数组。下面的代码可以,但是比较复杂,一定有更简单的解决方案。

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

【问题讨论】:

    标签: javascript arrays functional-programming underscore.js lodash


    【解决方案1】:

    如果你愿意,你可以用下划线写这个,但没有迫切需要这样做。

    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, ... ]?

    【讨论】:

    • 这真的很好,但并不完全符合我的要求。如果您运行代码,“key_2”将有两个单独的条目,因此必须有另一个按标签对数组进行分组的步骤。 [].concat(... x ) 实现了什么?我只会运行 input.map()
    【解决方案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>

    【讨论】:

    • 完美!这正是我一直在寻找的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-15
    相关资源
    最近更新 更多