admin管理员组

文章数量:1295332

The goal is to break an object of unknown length and shape into small objects 3 elements each. Only vanilla JS solution; I don't want to use _.pick etc.

Example of large object:

const data = {
    someFirstKey: 'someFirstVal',
    someSecondKey: 'someSecondVal',
    ...
    someLastKey: 'someLastVal'
}

Desired chunk with 3 keys:

{someKey0: 'someVal0', someKey1: 'someVal1', someKey2, 'someVal2'}

The goal is to break an object of unknown length and shape into small objects 3 elements each. Only vanilla JS solution; I don't want to use _.pick etc.

Example of large object:

const data = {
    someFirstKey: 'someFirstVal',
    someSecondKey: 'someSecondVal',
    ...
    someLastKey: 'someLastVal'
}

Desired chunk with 3 keys:

{someKey0: 'someVal0', someKey1: 'someVal1', someKey2, 'someVal2'}
Share edited Nov 13, 2018 at 18:42 Paul 142k28 gold badges284 silver badges271 bronze badges asked Nov 13, 2018 at 17:09 VonAxtVonAxt 951 silver badge9 bronze badges 13
  • 1 @VonAxt If the order of the items being returned is important, then the data should not be formatted as an object, but rather an array. If you always want the keys to be sorted alphabetically as in your example, that makes things easier - you can pull out the keys, sort them, and get their values in order. – Tyler Roper Commented Nov 13, 2018 at 17:18
  • 1 @VonAxt Object keys do not have positions. – Tyler Roper Commented Nov 13, 2018 at 17:21
  • 2 So wait, your goal is to break an object up into several smaller objects, but you don't care how it gets broken up as long as each small object has at most 3 keys? – Paul Commented Nov 13, 2018 at 17:22
  • 1 This looks like a homework problem. I can't imagine any valid business case for breaking an arbitrary data structure into smaller arbitrary data structures without knowing how they fit together or can get deserialized reliably. – Paul Commented Nov 13, 2018 at 17:27
  • 1 @VonAxt I agree w/ everyone else, this is a far better case for an array than an object. But see my answer. – Paul Commented Nov 13, 2018 at 17:56
 |  Show 8 more ments

5 Answers 5

Reset to default 9

Based on the ments, it seems like you are actually looking for a way to split an object up into several smaller objects. I would approach that like this:

const data = {a:1,b:2,c:3,d:4,e:5,f:6,g:7};

const chunk_size = 3, chunks = [];
for ( const cols = Object.entries( data ); cols.length; )
  chunks.push( cols.splice(0, chunk_size).reduce( (o,[k,v])=>(o[k]=v,o), {}));

console.log( chunks );

Ok, so this might not be the most efficient way, but it works on my box. ;)

const data = {} // fill in your data here
const keys = Object.keys(data); // gets you the keys from your obj. 
const numberOfWholeParts = Math.floor( keys.length / 3 );  // or whatever your size limit is
const remainder = keys.length % 2; // keys left after all whole parts are filled

const arrayOfParts = [];

for(let i=0;i<numberOfWholeParts;i++) {
   const obj = {};
   const keySegment = keys.slice(i*3, i*3+3);

   for(let j=0; j<3; j++) {
     obj[keySegment[j]] = data[keySegment[j]];
   }
   arrayOfParts.push(obj);
} 
if(remainder > 0){
  const obj = {};
  let remainingKeys = keys.slice(-remainder)
  for(let i=0; i<remainingKeys.length;i++) {
    obj[remainingKeys[i]] = data[remainingKeys[i]];
  }
  arrayOfParts.push(obj);
}

Using Object.fromEntries:

const entries = Object.entries(data);
const grouped = [];

for (let i = 0; i < entries.length; i++) {
    if (i % groupSize === 0) {
        grouped.push([entries[i]]);
    } else {
        grouped[Math.floor(i / groupSize)].push(entries[i]);
    }
}

const chunks = grouped.map(o => Object.fromEntries(o));

For the readers who would e here not necessarily in search of vanilla solution, but who would be happy with more expressive (even if slower) solutions, such a solution with Lodash would be

_.map(_.chunk(_.toPairs(obj), 3), _.fromPairs)

// input
obj = { k1: 'v1', k2: 'v2', k3: 'v3', k4: 'v4', k5: 'v5', k6: 'v6', k7: 'v7', k8: 'v8' };

// magic
res = _.map(_.chunk(_.toPairs(obj), 3), _.fromPairs)

// print
console.log(res)
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Using Object destructuring

const { someKey0, someKey1, someKey2 } = data

const newData = {
    someKey0,
    someKey1,
    someKey2
}

本文标签: javascriptHow to chunk an object into smaller objectsStack Overflow