簡體   English   中英

獲取數組的每個第 n 個元素

[英]Get every nth element of an array

我正在編寫一個輔助函數來獲取數組中的每個nth元素,以便根據列的索引獲取特定列的所有表單元格。

我基於這個線程的答案。

我擔心的是,每當我傳遞列索引 0 時,它都不起作用。 我也不太確定應該將增量更改為什么,因為它不會產生正確的結果。

給定以下數組

const cells = [
  'text', 'text', 'text', 'text', 'text', 'text', 'button',
  'text', 'text', 'text', 'text', 'text', 'text', 'button',
  'text', 'text', 'text', 'text', 'text', 'text', 'button',
];

並通過getColumnCells(cells, 6)調用該函數getColumnCells(cells, 6)我應該會收到一個“按鈕”數組。

const getColumnCells = (cells, columnIndex) => {
  const columnCells = [];
  const delta = Math.floor(cells.length / columnIndex);

  for (let i = columnIndex; i < cells.length; i = i + delta) {
    columnCells.push(cells[i]);
  }

  return columnCells;
};

getColumnCells(cells, 0)應該返回['text', 'text', 'text]以獲取每行的索引 0。

您可以使用簡單的過濾器% (模)運算來實現這一點。 但是您需要知道row的長度,因為看起來您想將一維數組視為二維數組。

解決方案:

 const cells = [ 'texta1', 'texta2', 'texta3', 'texta4', 'texta5', 'texta6', 'buttona', 'textb1', 'textb2', 'textb3', 'textb4', 'textb5', 'textb6', 'buttonb', 'textc1', 'textc2', 'textc3', 'textc4', 'textc5', 'textc6', 'buttonc', ]; const getEveryNth = (arr, rowLength, colIdx) => arr.filter( (_, i) => i % rowLength === colIdx ) console.log(getEveryNth(cells, 7, 6)) console.log(getEveryNth(cells, 7, 0))
 .as-console-wrapper { max-height: 100% !important; top: 0; } /* ignore this */

我建議在函數中再傳遞一個變量cols

您可以在將來的某一天再添加一列。

然后,您可以將cols不同參數傳遞給函數以獲取輸出。

 const cells = [ 'text', 'text', 'text', 'text', 'text', 'text', 'button', 'text', 'text', 'text', 'text', 'text', 'text', 'button', 'text', 'text', 'text', 'text', 'text', 'text', 'button', ]; function getColumnCells(arr, cols, index) { const output = []; if (cols > index) { for (let i = 0; i < arr.length; i += cols) { const row = arr.slice(i, i + cols); index > row.length ? output.push(null) : output.push(row[index]); } } return output; } console.log(getColumnCells(cells, 7, 6));

解決方案 1:您可以假設您有 7 列,並將其用作偏移量/增量。

    const cells = [
        'text', 'text', 'text', 'texts', 'text', 'text', 'button',
        'text', 'text', 'text', 'texts', 'text', 'text', 'button',
        'text', 'text', 'text', 'texts', 'text', 'text', 'button',
    ];

const getColumnCells = (cells, columnIndex) => {
    const columnCells = [];
    const numberOfColumns = 7
    const delta = numberOfColumns // or equals to number of columns
    for (let i = columnIndex; i < cells.length; i = i + delta) {
        columnCells.push(cells[i]);
    }

    return columnCells;
};
console.log(getColumnCells(cells, 3)) // ['texts','texts','texts']
console.log(getColumnCells(cells, 6)) // ['button','button','button']

解決方案 2:簡單的一個 3 行 7 列的數組。所以,重塑你的數據

const newCells = [
    ['text0', 'text1', 'text2', 'text3', 'text4', 'text', 'button'],
    ['text0', 'text1', 'text2', 'text3', 'text4', 'text', 'button'],
    ['text0', 'text1', 'text2', 'text3', 'text4', 'text', 'button'],
];
const getColumnCellsTwo = (cells, columnIndex) => {
    const columnCells = [];
    for (let k = 0; k < cells.length; k++) {
        columnCells.push(cells[k][columnIndex]);
    }

    return columnCells;

};


console.log(getColumnCellsTwo(newCells, 0)) // ['text0','text0','text0']
console.log(getColumnCellsTwo(newCells, 6)) // ['button','button','button']

//最后一條評論是:在你的代碼中,delta = Math.floor(cells.length / columnIndex) is Infinity when columnIndex = 0.只是為了澄清。

 const cells = ['text1', 'text2', 'text3', 'text4', 'text5', 'text6', 'button7']; function breakInN(arr, chunk) { chunk--; return arr.filter((x, i) => i % chunk == 0 && (i+chunk != 0) || chunk == 0); } const output = breakInN(cells, 1); console.log({ output })

const cells = [
  'text', 'text', 'text', 'text', 'text', 'text', 'button',
  'text', 'text', 'text', 'text', 'text', 'text', 'button',
  'text', 'text', 'text', 'text', 'text', 'text', 'button',
];

const getColumnCells = (cells, columnIndex) => {
  const columnCells = [];
  const delta = columnIndex + 1;

  // Starting at -1 (ignoring -1) so we always move by 7 and push the 7th element `button`
  for (let i = -1; i < cells.length; i = i + delta) {
    if (i != -1) {
      columnCells.push(cells[i]);
    }
  }

  return columnCells;
};

console.log(getColumnCells(cells, 6));

我想你的目標是能夠像矩陣/表格結構(基本上是二維數組)一樣處理cells 在進行任何過濾或選擇之前,您可以通過將一維數組轉換為實際矩陣來模擬該行為。 之后的任何工作都會變得容易得多。

如果您想按照您在問題中描述的方式處理一維數組,恐怕除了傳遞某種列數量和列索引之外別無他法。

 const cells = [ 'text0', 'text1', 'text2', 'text3', 'text4', 'text5', 'button', 'text0', 'text1', 'text2', 'text3', 'text4', 'text5', 'button', 'text0', 'text1', 'text2', 'text3', 'text4', 'text5', 'button', ]; const arrayToMatrix = (array, cols) => Array(Math.floor(array.length / cols)) .fill() .reduce((acc, _, i) => [...acc, [...array].splice(i * cols, cols)], []); const getColumnCells = (cells, cols, colIndex) => arrayToMatrix(cells, cols).map((e) => e[colIndex]); console.log(getColumnCells(cells, 7, 6)); console.log(getColumnCells(cells, 7, 0));

我的方法的缺點是你需要非常小心你傳遞給getColumCell()參數,因為arrayToMatrix()可能返回一個不完整的矩陣,因此你最終會得到undefined列值。

如果允許自己有足夠的時間來獲得更通用的解決方案,可以實現一個原型Array.nthItem方法,該方法受:nth-child() CSS 偽類的啟發,但使用基於零/ 0的索引而不是1 .. .

 const cells = [ 'texta1', 'texta2', 'texta3', 'texta4', 'texta5', 'texta6', 'buttona', 'textb1', 'textb2', 'textb3', 'textb4', 'textb5', 'textb6', 'buttonb', 'textc1', 'textc2', 'textc3', 'textc4', 'textc5', 'textc6', 'buttonc', ]; function processItem(nthItem, nthIndex, array) { console.log({ nthItem, nthIndex }); // - any passed argument can be processed. // - this callback is aware of it's `this` context. // - the callback's return value will be mapped to the // `nthItem`'s internal array of to be processed indices // which also, entirely mapped, is the `nthItem`'s return value. return nthItem; } console.log( "cells.nthItem('7n-1', processItem) ...", cells.nthItem('7n-1', processItem) ); console.log( "cells.nthItem('7n-5', processItem) ...", cells.nthItem('7n-5', processItem) );
 .as-console-wrapper { min-height: 100%!important; top: 0; }
 <!-- https://gist.github.com/petsel/86d7ce468512fffdb051bf9e650d1e4f //--> <script> const arrPrototype = Object.getPrototypeOf([]); const { from: arrayFrom, isArray, } = Array; function isFunction(type) { return ( (typeof type === 'function') && (typeof type.call === 'function') && (typeof type.apply === 'function') ); } function getSanitizedTarget(type) { return (type ?? null); } function getNotationGroup(notation) { // - inspired by `:nth-child()` CSS pseudo-class ... [https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child] // // - an array's `nth-item` notation ... [https://regex101.com/r/tZmeZS/1/] // const regXNthItemNotation = (/^(?<nthBase>[+-]?\\d+)(?:\\*?(?<series>n)(?<crementer>[+-]\\d+)?)?$/); const regXSanitizeNotation = (/\\s+/g); return String(notation) .replace(regXSanitizeNotation, '') .match(regXNthItemNotation) ?.groups; } function getNthIndexSeriesDescending(getNthIndex, maximumIndex) { const nthIndexList = []; let nthIndex; let n = -1; while ((nthIndex = getNthIndex(++n)) >= 0) { if (nthIndex <= maximumIndex) { nthIndexList.push(nthIndex); } } return nthIndexList; } function getNthIndexSeriesAscending(getNthIndex, maximumIndex) { const nthIndexList = []; let nthIndex; let n = -1; while ((nthIndex = getNthIndex(++n)) <= maximumIndex) { if (nthIndex >= 0) { nthIndexList.push(nthIndex); } } return nthIndexList; } function getNthIndexSeriesList(notationGroup, maximumIndex) { const nthIndexList = []; let { series, nthBase, crementer } = notationGroup; nthBase = Number(nthBase); crementer = Number(crementer ?? 0); const getNthIndex = n => ((nthBase * n) + crementer); if (!!series) { if (nthBase !== 0) { const isDescending = (getNthIndex(0) > getNthIndex(1)); nthIndexList.push( ...isDescending ? getNthIndexSeriesDescending(getNthIndex, maximumIndex) : getNthIndexSeriesAscending(getNthIndex, maximumIndex) ); } else if (crementer >= 0) { // `crementer` in this case equals the result of the first nth-index computation. nthIndexList.push(crementer); } } else if ((nthBase >= 0) && (nthBase <= maximumIndex)) { // just the `nthBase` as the sole nth-index item. nthIndexList.push(nthBase); } return nthIndexList; } function nthItem(notation, callback, target) { let result = []; const notationGroup = getNotationGroup(notation); const arr = notationGroup && ((isArray(this) && this) || arrayFrom(this ?? [])); // fail silently. const nthIndexList = arr && isFunction(callback) && getNthIndexSeriesList(notationGroup, (arr.length - 1)); if (nthIndexList && nthIndexList.length) { target = getSanitizedTarget(target); result = nthIndexList.map(nthIndex => callback.call(target, arr[nthIndex], nthIndex, arr) ); } return result; } Object.defineProperty(arrPrototype, 'nthItem', { configurable: true, writable: true, value: nthItem }); Object.defineProperty(arrPrototype.nthItem, 'toString', { value: () => 'function nthItem() { [custom code] }' }); // export default Array; </script>

暫無
暫無

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

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