获取数组的每个第 n 个元素 游乐场

如何解决获取数组的每个第 n 个元素 游乐场

我正在编写一个辅助函数获取数组中的每个 nth 元素,以便根据列的索引获取特定列的所有表格单元格。

我是根据 this thread 的回答得出的。

我担心的是,每当我传递列索引 0 时,它都不起作用。 我也不太确定应该将增量更改为什么,因为它不会产生正确的结果。

给定以下数组

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

并通过 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]获取每行的索引 0。

解决方法

您可以使用简单的 filter%(模)运算来实现这一点。但是您需要知道 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,0))
.as-console-wrapper { max-height: 100% !important; top: 0; } /* ignore this */

,

我建议在函数中再传递一个变量 cols

您可以在未来一天再添加一列。

然后,您可以将 cols 的不同参数传递给函数以获取输出。

const cells = [
  '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,6));

,

解决方案 1:您可以假设您有 7 列,并将其用作偏移量/增量。

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

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']
console.log(getColumnCells(cells,6)) // ['button','button']

解决方案 2:简单的一个 一个 3 行 7 列的数组。所以,重塑你的数据

const newCells = [
    ['text0','text1','text2','text3','text4','button'],['text0',];
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,'button']

//最后一条评论是:在您的代码中,当 columnIndex = 0 时,delta = Math.floor(cells.length / columnIndex) 为无穷大。只是为了澄清。

,

const cells = ['text1','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',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 视为矩阵/表状结构(基本上是 2d array)。在进行任何过滤或选择之前,您可以通过转换您的一维数组为实际矩阵来模拟该行为。以后的工作都会轻松很多。

如果您想按照您在问题中描述的方式处理一维数组,恐怕除了传递某种列数量和列索引之外别无他法。

const cells = [
  'text0',];

const arrayToMatrix = (array,cols) =>
  Array(Math.floor(array.length / cols))
    .fill()
    .reduce((acc,_,i) => [...acc,[...array].splice(i * cols,cols)],[]);

const getColumnCells = (cells,colIndex) =>
  arrayToMatrix(cells,cols).map((e) => e[colIndex]);

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

我的方法的缺点是你需要非常小心你传递给 getColumCell() 的参数,因为 arrayToMatrix() 可能返回一个不完整矩阵,因此你会结束列值为 undefined

,

如果给自己足够的时间来获得更通用的解决方案,则可以实现一个 prototypal Array.nthItem 方法,该方法通过 is inspired :nth-child() CSS pseudo-class 但基于零/0索引而不是 1 ...

const cells = [
  'texta1',];

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',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],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>

游乐场

九之七方法

... nth(7).of(9) ... 基于索引 1 ...

const cells = [
  'a1','a2','a3','a4','a5','a6','a7','a8','a9','b1','b2','b3','b4','b5','b6','b7','b8','b9','c1','c2','c3','c4','c5','c6','c7','c8','c9',];

console.log(
  "cells.nth(7).of(9).map(({ item }) => item) ...",cells.nth(7).of(9).map(({ item }) => item)
);

console.log(
  "cells.nth(7).of(9) ...",cells.nth(7).of(9)
);

console.log(
  "cells.nth(3).of(6) ...",cells.nth(3).of(6)
);
console.log(
  "cells.nth(2).of(3) ...",cells.nth(2).of(3)
);

console.log(
  "cells.nth ...",cells.nth
);
console.log(
  "cells.nth(2) ...",cells.nth(2)
);
console.log(
  "cells.nth(2).of ...",cells.nth(2).of
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
<!--

  https://gist.github.com/petsel/42d89ad83cc5e90dc0f61a4d030fc17d

//-->
<script> 
const
  arrPrototype = Object.getPrototypeOf([]);

const {
  from: arrayFrom,} = Array;

function createListOfChunkLists(arr,chunkCount) {
  return arr.reduce((list,item,idx) => {
    if (idx % chunkCount === 0) {

      list.push([ item ]);
    } else {
      // list.at(-1).push(item);
      list[list.length - 1].push(item);
    }
    return list;
  },[]);
}

function getNthItemOfChunkCount(arr,chunkCount) {
  if (!isArray(arr)) {
    throw (new TypeError(
      'The "nth().of()" chain needs to operate a list like structure.'
    ));
  }
  if (Number.isNaN(chunkCount)) {
    throw (new TypeError(
      'The chunk count needs to be an integer value.'
    ));
  }
  if (chunkCount > arr.length) {
    throw (new RangeError(
      "The chunk count value has to be lower than or equal to the operated list structure's length."
    ));
  }
  if (
       Number.isNaN(nthIndex)
    || (nthIndex < 0)
  //|| ((nthIndex < 0) && ((nthIndex + chunkCount) <= 0))
    || ((nthIndex >= 0) && ((nthIndex + 1) >= chunkCount))
  ) {
    throw (new RangeError(
      "The nth index needs to be an integer value which has to be reasonable within the chunk count's context."
    ));
  }
  return createListOfChunkLists(arr,chunkCount)
    .map((chunkList,idx) => ({

      item: chunkList[nthIndex],idx: ((idx * chunkCount) + nthIndex),}));
}

class NthItemOfChunkCount {
  #arr;
  #idx;
  constructor(arr,idx) {
    this.#arr = arr;
    this.#idx = idx;
  }
  of(int) {
    return getNthItemOfChunkCount(this.#arr,this.#idx,parseInt(int,10));
  }
}

function nthItemOfChunkCount(int) {
  const arr = (isArray(this) && this) || arrayFrom(this ?? []);
  const idx = parseInt(int,10) - 1;

  return (new NthItemOfChunkCount(arr,idx));
}

Object.defineProperty(arrPrototype,'nth',value: nthItemOfChunkCount
});
Object.defineProperty(arrPrototype.nth,{
  value: () => 'function nth() { [custom code] }'
});

Object.defineProperty(NthItemOfChunkCount.prototype.of,{
  value: () => 'function of() { [custom code] }'
});

// export default Array;
</script>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?