Partition Javascript array of primitive types into multiple parts

丶灬走出姿态 提交于 2019-12-10 17:47:37

问题


I want to be able to partition an unordered array of primitive types like so:

var array = [102,103,104,201,203,204,303,301,302,405,406,408,101];

=>

newArray = [[101,102,103,104],[201,203,204],[303,301,302],[405,406,408]]

The array gets partitioned into segments based upon the first integer.

The array would be partitioned based on something similar to this expression:

array[i]/100|0 === j;

where j could be 1,2,3, or 4.

eg. 405/100|0 === 4 // partition into the array starting with 4.

Does anyone know of a way that I could efficiently filter this array into sections based on the first number?

I'm aware that I could use the lodash partition function with collections, but I need to inital array to be only primitive types for speed. Even then, the partition would only part the array into 2 parts.

Thanks in advance!


回答1:


You may use lodash function chaining like

var array = [404,101,102,103,104,201,203,204,303,301,302,405,406,408];
var newArray = _(array)
  .groupBy(function (x) { return x / 100 | 0; })
  .values()
  .value();



回答2:


You might do as follows ;

var arr = [102,103,104,201,203,204,303,301,302,405,406,408,101],
 result = arr.reduce((res,e) => { var idx = e/100|0;
                                  res[idx-1] = res[idx-1] ? res[idx-1].concat(e) : [e];
                                  return res;
                                },[])
             .map(subarr => subarr.sort((a,b) => a-b));
console.log(result);



回答3:


Array.reduce appears to be called for :

var a = [102,103,104,201,203,204,303,301,302,405,406,408,101];

a.reduce (
  function (r, v) { 
    var d = +v.toString ().slice (0,1);
    r[d] && r[d].push (v) || (r[d] = [v]);
    return r; 
  }, [])



回答4:


Correct me if I'm wrong. You have an array containing integers like [101, 102, 103, 201, 202, 203] and you want to convert it to an array of arrays containing integers starting with the same integer like [[101, 102, 103], [201, 202, 203]].

So, here is a simple solution:

// This object will contain partitioned array
var newObject = {};

for(var i = 0; i < arr.length; i++) {
  var index = arr[i] / 100;
  if(index in newObj)
    newObj[index].push(arr[i]);
  else
    newObj[index] = [arr[i]];
}

After this you will get an object with properties like 1,2,3 which in return will contain array of numbers starting from indices 1,2,3.

Now, if you want array of arrays

var newArr = [];
$(newObj).each(function() {newArr.push(this)});

Let me know if you have any queries.




回答5:


This uses lodash's groupBy functionality:

var array = [404,101,102,103,104,201,203,204,303,301,302,405,406,408];

var grouped = _.groupBy(array, function(x) {return x.toString()[0]});

var newArray = []
for (var key in grouped) {
    newArray.push(grouped[key]);
}



回答6:


First, you'd want to sort your array. You can do this however you'd like, but for this example I'll use quicksort. Time complexity would be O (n * log n).

Keep in mind, I am doing everything here more or less from scratch (not using built in methods), so you can see how it is being done. I don't really find it helpful when learning to just use functions that do all of the work for you because then you don't see what's going on.

Start with an unsorted array:

let unsortedArray = [403, 101, 203, 102, 302, 103, 201, 202, 301, 303, 401, 402];

Here is our recursive quicksort function:

let quicksort = arr => {
        if (arr.length < 2) {
            return arr;
    }

    let pivotIndex = rand(0, arr.length),
        pivot = arr[pivotIndex],
        less = [],
        more = [],
        sorted = [];

    for (let i = 0, len = arr.length; i < len; i++) {
        if (pivotIndex !== i) {
            if (arr[i] > pivot) {
                more.push(arr[i]);
            } else {
                less.push(arr[i]);
            }
        }
    }

    return sorted.concat(quicksort(less)).concat([pivot]).concat(quicksort(more));
};

let rand = (min, max) => {
    return Math.floor( Math.random() * (min - max) + max );
};

Call the function on an unsorted array:

let sortedArray = quicksort(unsortedArray);

Now we get:

[101, 102, 103, 201, 202, 203, 301, 302, 303, 401, 402, 403]

Great, so now the array is sorted.

Let's partition this array into groups, to make it look like this:

[ [101, 102, 103], [201, 202, 203], [301, 302, 303], [401, 402, 403] ]

Using a bit of Redu's solution, here is our partition function:

let partition = arr => { 
    return arr.reduce((prev, curr) => { 
        let remainder = curr % 100;

        if (prev[remainder - 1]) {
            prev[remainder - 1] = prev[remainder - 1].concat(curr);
        } else {
            prev[remainder - 1] = [curr];
        }

        return prev;
    }, []);
};

Now call partition on the sorted array:

let partitionedArray = partition(sortedArray);

...and voila! We get [ [101, 102, 103], [201, 202, 203], [301, 302, 303], [401, 402, 403] ].



来源:https://stackoverflow.com/questions/39178029/partition-javascript-array-of-primitive-types-into-multiple-parts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!