【问题标题】:Split an array with custom function使用自定义函数拆分数组
【发布时间】:2019-03-14 13:41:34
【问题描述】:

我想将一个数组拆分为多个块,但对其应用一个函数来决定如何创建这些块。

例如,如果我有一个由字母、数字或字母和数字组成的数组,则对数组应用一个函数以将其拆分为先前类别的数组数组。

let arr = ['a', 'b', '1', '2', 'a1', 'a2', 'c', '3', 'a3']
myChunkFunction(arr, myCustomSplitFunction)

// result
[['a','b','c'], ['1','2','3'], ['a1', 'a2','a3']]

Lodash 有一个块函数,但它会拆分为 n 个块,数组也有一个切片函数,但您需要指定开始和结束,所以我如何使用自定义函数进行拆分。

【问题讨论】:

  • 问题是什么?你有什么似乎很好,你只需要定义myCustomSplitFunction
  • 我没有应用自定义函数的块函数。
  • 它只是function myChunkFunction(array, splitFunction) { return splitFunction(array); },然后您可以完全按照上面代码中的方式调用它。
  • 如果你需要经常做这样的操作,也许可以考虑使用像lodash这样的库。特别是,您可以通过他们的 _.groupBy_.values 函数轻松地做到这一点。
  • 这个问题很好。停止投票只是因为你没有看到:“我的问题是......”。

标签: javascript arrays algorithm ecmascript-6 split


【解决方案1】:

这是通过 ES6 执行此操作的一种方法:

let arr = ['a', 'b', '1', '2', 'a1', 'a2', 'c', '3', 'a3']

const splitFn = (str) => Number.isInteger(+str) ? 0 : str.length == 1 ? 1 : 2
const myChunkFunction = (arr, fn) => arr.reduce((r,c) => {
   let t = fn(c)
   r[t] = [...r[t], c]
   return r
}, [[],[],[]])

console.log(myChunkFunction(arr, splitFn))

typeFn 起到将元素过滤到numberstring with 1 lengthother 的作用。 myChunkFunction 使用该输出将元素放入正确的数组中。

您可以在控制较少的情况下使用reduce 和 ES6 数组传播来做这样的事情:

let arr = ['a', 'b', '1', '2', 'a1', 'a2', 'c', '3', 'a3']

const result = arr.reduce((r,c) => 
  (Number.isInteger(+c) ? r[0] = [...r[0], c] : 
  c.length == 1 ? r[1] = [...r[1], c] : r[2] = [...r[2], c], r), [[],[],[]])

console.log(result)

您从[[],[],[]] 开始,并根据数字、字符串长度 == 1 和其他长度填充每个子数组。

您可以将其包装在一个函数中。

【讨论】:

  • 他想通过给定函数从每个元素中提取一个键,并用它来重新组合元素。在您的解决方案中,您隐式使用身份函数来提取密钥。
  • “我想将一个数组拆分成多个块但应用一个函数来决定如何创建这些块”。并且:myChunkFunction(arr, myCustomSplitFunction)。第二个参数是自定义函数。
【解决方案2】:

提示

答案的关键是,以某种方式重新组织源数组,使具有相同键的所有元素都位于同一个位置。

我能想到的最简单的解决方法是使用hash-maphash-map 中的每个元素将是一个不同的数组,其中包含具有相同键的所有元素。

在继续阅读并查看完整解决方案之前,请亲自尝试一下。


实现

如您所见,我尽可能地解决了它。为了避免突变,我使用reduce 遍历源数组并将每个元素放入哈希图中(通过从元素生成一个键)。

我使用浅拷贝一遍又一遍地重新创建最终的哈希映射。最后,我使用Object.values 将哈希映射转换为数组数组(因为这是您的要求)

const splitArrayByKey = extractKey => array => {
    const arraysByKey_obj = array.reduce((hashMapOfArrays,element)=> {
        const key = extractKey(element);
        
        // if we already added an element with the same key, 
        // then we add the current element to there.
        // else, we create a new key and put the current element there.
        if(hashMapOfArrays.hasOwnProperty(key))
            return {
                ...hashMapOfArrays,
                [key]: [...hashMapOfArrays[key],element]
            };
        return {
            ...hashMapOfArrays,
            [key]: [element]
        };
    },{});

    // transform the arraysByKey_obj to an array of arrays:
    return Object.values(arraysByKey_obj);
};

// example 1:
const result1 = splitArrayByKey(element=>element)([1,2,3,1,2,3]);
console.log(result1);

console.log('------------------');

// example 2:
const result2 = splitArrayByKey(element=>element.id)([{id:1,x:1},{id:{},x:2},{id:"id",x:3},{id:1,x:4}]);
console.log(result2);

【讨论】:

    【解决方案3】:
    const arr = ['a', 'b', '1', '2', 'a1', 'a2', 'c', '3', 'a3'];
    const getClassification = function(x){
        const hasNumber = x.split('').some(x => parseFloat(x));
        const hasChar = x.split('').some(x => !parseFloat(x));
    
        if(!parseFloat(x) && (!hasNumber && hasChar)) return 0;
        else if(parseFloat(x)) return 1;
        else return 2;
    }
    
    const myChunkFunction = function(arr, classifier){
        let jaggedArray = [[], [], []];
    
        arr.forEach(x => {
            jaggedArray[classifier(x)].push(x);
        })
    
        return jaggedArray;
    }
    
    console.log(myChunkFunction(arr, getClassification));
    

    我认为这很满足。

    【讨论】:

      【解决方案4】:

      尝试这样做

      let arr = ['a', 'b', '1', '2', 'a1', 'a2', 'c', '3', 'a3']
      
      const splitFn = (str) => Number.isInteger(+str) ? 0 : str.length == 1 ? 1 : 2
      const myChunkFunction = (arr, fn) => arr.reduce((r,c) => {
         let t = fn(c)
         r[t] = [...r[t], c]
         return r
      }, [[],[],[]])
      
      console.log(myChunkFunction(arr, splitFn))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-07
        • 1970-01-01
        • 2011-12-27
        • 2019-09-04
        • 2014-07-30
        • 2015-11-07
        • 2017-11-05
        • 1970-01-01
        相关资源
        最近更新 更多