最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Creating subarrays in array - Stack Overflow

programmeradmin1浏览0评论

I'm attempting to create subarrays within an array that contains groupings of like numbers. I'm coding in JavaScript.

My array is [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];

I've sorted the array so its numbers are in order, I figured it would be easier to work with.Below is a visual of what I want to acplish.

Example:

array = [ 1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591 ]; 

output: [[1,1,1,1], [2,2,2],4,5,10,[20,20],391,392,591]; 

Thank you to anyone able to help!

I'm attempting to create subarrays within an array that contains groupings of like numbers. I'm coding in JavaScript.

My array is [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];

I've sorted the array so its numbers are in order, I figured it would be easier to work with.Below is a visual of what I want to acplish.

Example:

array = [ 1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591 ]; 

output: [[1,1,1,1], [2,2,2],4,5,10,[20,20],391,392,591]; 

Thank you to anyone able to help!

Share Improve this question edited Apr 5, 2020 at 0:39 Mechanic 5,3904 gold badges19 silver badges42 bronze badges asked Apr 5, 2020 at 0:37 user13224810user13224810 311 silver badge4 bronze badges 2
  • I don't understand why this question has been closed. It seems pretty straightforward to me. – Kevin Amiranoff Commented Apr 5, 2020 at 0:45
  • 1 @KevinAmiranoff it might have been not clear in the beginning. I voted to re-open. – Ivan86 Commented Apr 5, 2020 at 0:45
Add a ment  | 

5 Answers 5

Reset to default 3

The solution

let array = [ 1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591 ]; 

let temp = {};
array.forEach( el => {
  if(temp[el] != null){
    temp[el].push(el)
  }else{
    temp[el] = [el]
  }
})

let output = Object.values(temp).map(e=>e[1]?e:e[0]);

console.log(output)

The Funny version :)

__={};
[ 1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591 ]
.forEach(_=>__[_]?__[_].push(_):__[_]=[_]);
__=Object.values(__).map(_=>_[1]?_:_[0]);
console.log(__);

Disclaimer: this snippet is here only for entertainment purposes, I strongly discourage you to use it in production

sort() the numbers, reduce() to arrays, and map() to take the numbers that occur a single time out of their array:

let arr =  [ 1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591 ]

let sort = arr.sort((a,b) => a - b)

let res = sort.reduce((acc,cur) => {
    if(acc[acc.length-1] && cur === acc[acc.length-1][0]){
        acc[acc.length-1].push(cur)
    }else{
        acc.push([cur])
    }
    return acc
},[]).map(el => el.length === 1 ? el[0] : el)

console.log(res)

this can be achieved using an object as a holder and then the Object.values function to get the different entries.

so, this process will create something like

just an example
{
    1: [1,1,1,1],
    2: [2,2,2]
    5: 5,
    etc.....
}

and then executing Object.values will give us the right values from each key, returning something like

[
    [1,1,1,1],
    [2,2,2],
    5,
    etc....
]

you have a working example here, read carefully, we had to add that extra if inside, just to get the values alone, otherwise it would get something like [5].

const array = [1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591];

// we create an object using as key the values.
const reducerFN = (accumulation, value) => {
  const hasKey = accumulation[value];
  // if the key exist, we have our array/value, lets push.
  if (hasKey) {
    // if it is an array, we push the value
    if (Array.isArray(accumulation[value])) {
      accumulation[value].push(value)
    } else {
      // otherwise, we initialize the array with 2 values(the new one and the old one)
      accumulation[value] = [value, value]
    }
  } else {
    // just initialize the value.
    accumulation[value] = value
  }
  return accumulation
}

// use reduce with the reducerFN
const pre_result = array.reduce(reducerFN, {});

// we have our map easy to read.
// now lets get the values, and it is as easy as this:
const result = Object.values(pre_result)

console.log(result);

Since you have sorted the array, I think just reduce is sufficient:

let array = [ 1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591 ];
let output = array.reduce((accumulator, currentValue) => {
  if(accumulator.length > 0) {
    let last = accumulator.length - 1;
    if(Array.isArray(accumulator[last])){
      if(-1 !== accumulator[last].indexOf(currentValue)){
        accumulator[last].push(currentValue)
        return accumulator;
      }
    }else if(currentValue === accumulator[last]){
      accumulator[last] = [accumulator[last], currentValue]
      return accumulator;
    }
  }
  accumulator.push(currentValue);
  return accumulator;
}, []);
console.log(output);

You can group each element into an array using .reduce() and a Map. Whenever you see a number in your array, you can check the map and see whether it is a key. If it is a key, then that number has already previously been seen. The value for each key (ie: number) can hold the frequency of each number and how many times it has been seen. If the number isn't in the Map, you can add it and set its frequency to 1. Once you have created the map using .reduce(), you can use Array.from(), by using the map as the first argument and adding a mapping function as the second argument. The second mapping function gets called for every key-value pair in the map. If the frequency value is greater than one, you can create an array from these values, if it is equal to one then you can return the number itself:

const arr = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
const res = Array.from(
  arr.sort((a, b) => a - b)
    .reduce((map, n) => map.set(n, (map.get(n) || 0) + 1), new Map), 
  ([n, freq]) => freq > 1 ? Array(freq).fill(n) : n
);
console.log(res);

You could also set the values to arrays, and then concatenate to the array preexisting array. When you map, you can return the array or the first value in the array:

const arr = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
const res = Array.from(
  arr.sort((a, b) => a - b)
    .reduce((map, n) => map.set(n, (map.get(n) || []).concat(n)), new Map).values(), 
  g_arr => g_arr.length > 1 ? g_arr : g_arr.shift()
);
console.log(res);

发布评论

评论列表(0)

  1. 暂无评论