Input: 2D array

[ [2,3,4,5], [3,2,4,5], [2,3,8,5], [6,1,23,5], [2,1,23,5], [6,8,2,2] ] 

We need to find arrays with the same first elements (in this case c (2))

 [2,3,4,5] [2,1,23,5] [2,3,8,5] [6,1,23,5] [6,8,2,2] 

And write them in a separate array. Problem: how to find a match, so that the search for a match would not give duplicates. In this case, I find a match with 3 and 6 for the first array, then I find it with 1 and 6 for 3, and so, if we allow more arrays, or more ( not with (2) as in the example) more matches

  • Give your code. - Sasha Omelchenko
  • Decision head-on: at the beginning of the cycle, run and take the first element from the arrays, write it into the array ...... then consider which elements in the array> 1 (that is, there are matches on the first elements) ...... then you do another loop through the arrays, comparing with the first array (where the elements with the number> 1 were) placing each of the arrays to the corresponding key O_o - Alexey Shimansky
  • @ Alexey Shimansky, why are there two passes? - Grundy
  • @Grundy in the sense instead of the first cycle to use array_column ? yes you can ...... or are you still about something? - Alexey Shimansky
  • @ AlekseyShimansky, there are no godless array_column in js :-D - Grundy

1 answer 1

For grouping an array it is convenient to use the reduce method. In order not to run through the array twice, you can save the current index of the group with the maximum number of elements and the group itself.

The code might look like this:

 var src = [ [2, 3, 4, 5], [3, 2, 4, 5], [2, 3, 8, 5], [6, 1, 23, 5], [2, 1, 23, 5] ]; var dest = src.reduce((acc, cur) => { let key = cur[0]; if (!acc.map[key]) { acc.map[key] = []; } acc.map[key].push(cur); if (isNaN(acc.maxKey) || acc.maxKey != key && acc.map[acc.maxKey].length < acc.map[key].length) { acc.maxKey = key; acc.result = acc.map[key]; } return acc; }, { map: {}, maxKey: NaN, result: null }); console.log(dest.result); 


For the updated question, you need to add to the result array those elements that are already repeated. The code might look like this:

 var src = [ [2, 3, 4, 5], [3, 2, 4, 5], [2, 3, 8, 5], [6, 1, 23, 5], [2, 1, 23, 5], [6, 8, 2, 2] ] var dest = src.reduce((acc, cur) => { let key = cur[0]; if (!acc.map[key]) { acc.map[key] = []; } if (acc.mapCount[key]) { // если ключ уже повторялся acc.result.push(cur); // добавляем сразу в результат return acc; } acc.map[key].push(cur); if (acc.map[key].length == 2) { // если ключ повторяется acc.mapCount[key] = true; // выставляем флаг acc.result.push(...acc.map[key]); // переносим в результат } return acc; }, { map: {}, mapCount: {}, result: [] }); console.log(dest.result); 

  • something is not clear ... do you group only if the number 2 is at the beginning? and if there are more arrays, for example, from 3 or 6 at the beginning - spit?) - Alexey Shimansky
  • no, I collapse the array into an object, where the key is the first element of the subarray, and the value is an array containing the array in which the first element is equal to the key. - Grundy
  • one
    In general, kmk, this is wrong ... because with the initial array, var src = [ [2, 3, 4, 5], [3, 2, 4, 5], [3, 211, 4111, 511], [2, 3, 8, 5], [6, 1, 23, 5], [2, 1, 23, 5], [6, 1, 66, 666], ]; we get [2, 3, 4, 5], [2, 3, 8, 5], [2, 1, 23, 5] ..... but should be split into duplicate keys ... that is, with 3 - two arrays, from 6 - two and from 2 - three - Alexey Shimansky
  • @ Alexey Shimansky, I understood from the question that a maximum subgroup is needed. In any case, the map is going, you can choose anything from it - Grundy
  • one
    @ MoJlo4HuK, add more examples to the question, what should be the output - Grundy