我想将一个数组拆分为多个块,但对其应用一个函数来决定如何创建块。
例如,如果我有一个字母,数字或字母和数字组成的数组,请对该数组应用一个函数,以将其拆分为先前类别的数组。
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个块,数组也有切片函数,但是您需要指定开始和结尾,所以我如何使用自定义函数进行拆分。
答案 0 :(得分: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
的作用是将元素过滤到number
,string with 1 length
和other
。 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,其他长度填充每个子数组。
您可以将其包装在函数中。
答案 1 :(得分:1)
答案的关键是以某种方式重组源数组,以使所有具有相同关键点的元素都位于同一位置。
我想解决这个问题的最简单方法是使用hash-map
。 hash-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);
答案 2 :(得分:1)
尝试这样做
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))
答案 3 :(得分:0)
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));
我认为这令人满意。