簡體   English   中英

javascript根據另一個更大的數組創建具有固定長度的對象數組

[英]javascript create array of objects with a fixed length based on another bigger array

給定一個偶數長度的數組:

const items = [
  'this/is/path1',
  'this/is/path2',
  'this/is/path3',
  'this/is/path4',
  'this/is/path5',
  'this/is/path6'
];

我想創建將具有一定長度objnb的對象數組。 基於此長度,我將上述items分為多個塊,然后將第一個索引存儲在新的對象屬性path ,並將隨后的元素存儲在other1other2 其他對象塊也一樣。

我的解決方案很hacky:

const objnb = 2;
const other1 = true;
const other2 = true;
const outputobjs = items.length / objnb;
const result = items.map((entry, index) => {
  let obj = {};
  console.log({ entry, index })
  if (index % outputobjs === 0) {
    obj.path = entry;
    obj.others = {};
    if (other1) {
      obj.others.two = items[index + 1];
    }
    if (other2) {
      obj.others.three = items[index + 2];
    }

    return obj;
  }

  return obj;
})


console.log('result: ', result)

輸出正確:

[ { path: 'this/is/path1',
    others: { two: 'this/is/path2', three: 'this/is/path3' } },
  {},
  {},
  { path: 'this/is/path4',
    others: { two: 'this/is/path5', three: 'this/is/path6' } },
  {},
  {} ]

但不幸的是,我得到了我不想要的空物體。 我如何以更簡潔的方式實現相同目標?

首選結果將不包含空對象。

更新

另一個例子是:

const items = [
  'this/is/path1',
  'this/is/path2',
  'this/is/path3',
  'this/is/path4'
];

const objnb = 2;
const other1 = true;
const other2 = false;
const outputobjs = items.length / objnb;
const result = items.map((entry, index) => {
  let obj = {};
  console.log({ entry, index })
  if (index % outputobjs === 0) {
    obj.path = entry;
    obj.others = {};
    if (other1) {
      obj.others.two = items[index + 1];
    }
    if (other2) {
      obj.others.three = items[index + 2];
    }

    return obj;
  }

  return obj;
})


console.log('result: ', result)

結果是:

[ { path: 'this/is/path1', others: { two: 'this/is/path2' } },
  {},
  { path: 'this/is/path3', others: { two: 'this/is/path4' } },
  {} ]

澄清:

新數組中的每個對象都將相似,例如,它們都將具有path ,並且由於我們均勻地划分了原始數組,因此新對象將具有所有相同的屬性。 例如,如果一個具有two ,則新數組中的其余對象都將具有此屬性,如果應該具有three ,則它們都將具有該屬性。

新對象將如下所示:

{ path: 'this/is/path1',
    others: { 
       two: 'this/is/path2', 
       three: 'this/is/path3' // optional; if one object has this, others must have it too.
    }
}

因此,基本上,通過將原始項數組划分為特定的數(2、3、4等),我們會將其分塊為更小的數組,新的對象path將為chunkedArray[0] ,如果有一個這個新的分塊數組中有更多的項目,那么two將是chunkedArray[1] ,如果還剩下一個,那么three將是chunkedArray[2]

因此,如果我們將其除以2,則將得到:

const chunkedArray1 = [
  'this/is/path1', // path
  'this/is/path2', //others.two
  'this/is/path3' //others.three
];

const chunkedArray2 = [
  'this/is/path4',// path
  'this/is/path5',//others.two
  'this/is/path6'//others.three
];

因此新對象將具有twothree ;

但如果將其分為3,則將有:

const chunkedArray1 = [
  'this/is/path1',// path
  'this/is/path2'//others.two
];

const chunkedArray2 = [
  'this/is/path3',// path
  'this/is/path4'//others.two
];

const chunkedArray3 = [
  'this/is/path5',// path
  'this/is/path6'//others.two
];

因此我們只有一個路徑,每個對象只有two

每個新的chunkedArray的長度至少為2,這意味着路徑和two存在於每個新對象中。

另一個例子:

一個基本的例子是,如果原始數組是三個,那么我們就不能將其平均划分為較小的塊,因此:

const items = [
  'this/is/path1', //path
  'this/is/path2',//others.two
  'this/is/path3'//others.three
];

如果原始數組為兩個長度,則在此處相同:

const items = [
  'this/is/path1', //path
  'this/is/path2',//others.two
];

以下是使用reduce一種解決方案。

 const items = [ 'this/is/path1', 'this/is/path2', 'this/is/path3', 'this/is/path4', 'this/is/path5', 'this/is/path6' ] function splitItems(data, chunkSize) { if (chunkSize < 2) return data // or the special value you'd like. const labels = { 1: 'one', 2: 'two', 3: 'three', 4: 'four' // ... others } return data.reduce((pre, cur, index) => { if (index % chunkSize === 0) { /* for old question pre.push({ path: cur, others: {} })*/ let newItem = { path: cur, others: {} } Array.from(Array(chunkSize-1).keys()).map( itemIndex => { newItem.others[labels[(itemIndex+1) % chunkSize + 1]] = '' //or other default valu }) pre.push(newItem) } else { pre[pre.length - 1].others[labels[index % chunkSize + 1]] = items[index] } return pre }, []) } console.log('@Test Case 1@', splitItems(items, 2), '@@') console.log('@Test Case 2@', splitItems(items.slice(0, 2), 2), '@@') console.log('@Test Case 3@', splitItems(items.slice(0, 4), 2), '@@') console.log('@Test Case 4@', splitItems(items.slice(0, 5), 3), '@@') // calc the size first, then exec splitItems function splitByLength(data, numberOfChunks) { let chunkSize = Math.round(data.length/3, 0) return splitItems(data, chunkSize) } console.log('@Test Case 5@', splitByLength(items.slice(0, 5), 3), '@@') 

簡而言之,您可以循環每3個項目並將其作為對象推送。

 const items = [ 'this/is/path1', 'this/is/path2', 'this/is/path3', 'this/is/path4', 'this/is/path5', 'this/is/path6' ]; var result = []; for(var i = 0; i < items.length; i++){ if(i%3==0){ result.push({ path: items[i], others: {two: items[i+1] || null, three: items[i+2] || null} }) } } console.log(result) 

另一個使用reduce的解決方案,盡管與@sphinx答案有些許不同,但它有點類似:

const objnb = 3;
const otherKeys = ['two', 'three'];

const items = [
  'this/is/path1',
  'this/is/path2',
  'this/is/path3',
  'this/is/path4',
  'this/is/path5',
  'this/is/path6'
];

const outputobjs = Math.ceil(items.length / objnb);

const ar = items.reduce((memo, item, index) => {
  const mod = index % outputobjs
  if(mod === 0)
    memo.push({path: item, others: {}});
  else if(mod <= otherKeys.length)
    Object.assign(memo[memo.length - 1].others, {[otherKeys[mod -1]]: item});
  return memo;
}, []);

console.log(ar);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM