我知道如何提取数组中的每个第n项,但我遇到的困难如下:
如何从1800个元素的数组中提取每个第n个项目,总是包括第一个和最后一个元素,最多总共256个元素?
示例:
array = [1,2,3,4,5,6,7,8,9,10];
提取5个元素:
extract = [1,3,5,7,10];
答案 0 :(得分:3)
喜欢这个吗?
/**
* Retrieve a fixed number of elements from an array, evenly distributed but
* always including the first and last elements.
*
* @param {Array} items - The array to operate on
* @param {Number} n - The number of elements to extract
* @returns {Array}
*/
function distributedCopy(items, n) {
var elements = [items[0]];
var totalItems = items.length - 2;
var interval = Math.floor(totalItems/(n - 2));
for (var i = 1; i < n - 1; i++) {
elements.push(items[i * interval]);
}
elements.push(items[items.length - 1]);
return elements;
}
示例:
// Set up an array for testing purposes
var items = [];
for (var i=1; i<= 1800; i++) {
items.push(i);
}
var extracted = distributedCopy(items, 256);
console.log(extracted);
答案 1 :(得分:3)
我以前的回答略有改善
function evenlyPickItemsFromArray<T>(allItems: T[], neededCount: number) {
// if we want more items than avaliable, return all items
if (neededCount >= allItems.length) {
return [...allItems];
}
// buffer for collecting picked items
const result: T[] = [];
const totalItems = allItems.length;
// default interval between items (might be float)
const interval = totalItems/neededCount;
for (let i = 0; i < neededCount; i++) {
// always add half of interval, so 'picking area' is 'aligned' to the center
// eg evenlyPickItemsFromArray([0...100], 1); // [50] instead of [0]
const evenIndex = Math.floor(i * interval + interval / 2);
result.push(allItems[evenIndex]);
}
return result;
}
// TESTING
// helper to create 0...n array
function createNLongArray(n: number) {
return Array.from({length: n}).map((_, i) => i);
}
console.log(evenlyPickItemsFromArray(createNLongArray(100), 20)) // [2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 77, 82, 87, 92, 97]
console.log(evenlyPickItemsFromArray(createNLongArray(200), 3)) // [33, 100, 166]
请注意,它并不是每次都选择第一个/最后一个元素,因为它实际上很复杂-例如。如果我选择1个elem-我应该选择第一个还是最后一个,等等。它只是查找均匀分布并选择它们。仅当您需要输入数组中的所有或几乎所有元素时,才会选择第一和最后一个
答案 2 :(得分:0)
基本答案是写
array.filter(filterFunc)
为参数为filterFunc
,elt
和index
的每个元素调用array
,并且应该返回true
或false
取决于您是要过滤还是过滤该元素。
所以你需要写filterFunc
。要做到这一点,你必须在脑海中清楚地定义。例如,这是一个根据您要提取的元素数量创建filterFunc
的函数:
function makeFilterFunc(howMany) {
return function filterFunc(elt, idx, arr) {
return idx === 0 || // first element
idx === arr.length-1 || // last element
idx % Math.floor(arr.length / howMany) === 0;
};
}
现在
filterFunc = makeFilterFunc(256);
array.filter(filterFunc)
< Array[258]
答案 3 :(得分:0)
@ pie6k算法的视觉演示 https://codepen.io/renderlife/pen/GRoxgZj
HTML
<h2>Original array</h2>
<div class="chart js-chartData"></div>
<h2>Evenly reduced array (saved element is green)</h2>
<div class="chart js-chartResult"></div>
CSS
.chart {
background: #aaaebc;
display: flex;
flex-wrap: wrap;
padding: 10px;
margin-bottom: 15px;
}
.chart .bar {
text-align: center;
font-size: 10px;
background: #d5d7de;
margin: 2px;
min-width: 5%;
height: 50px
display: inline-block;
color: black;
}
.chart .bar.save {
background: green;
}
JS / JQuery
elementsInArray = 365
neededCountElementsInArray = 234
function createNLongArray(n) {
return Array.from({length: n}).map((_, i) => i + 1);
}
function evenlyPickItemsFromArray(allItems, neededCount) {
if (neededCount >= allItems.length) {
return [...allItems]
}
const result = []
const totalItems = allItems.length
const interval = totalItems / neededCount
for (let i = 0; i < neededCount; i++) {
const evenIndex = Math.floor(i * interval + interval / 2)
result.push(allItems[evenIndex])
}
return result
}
array = createNLongArray(elementsInArray)
array.map(i => $('.js-chartData').append('<span class="bar">' + i + '</span>'))
elementsSave = evenlyPickItemsFromArray(array, neededCountElementsInArray)
console.log(elementsSave)
array.map(i => {
if (elementsSave.includes(i)) {
$('.js-chartResult').append('<span class="bar save">' + i + '</span>')
} else {
$('.js-chartResult').append('<span class="bar">' + i + '</span>')
}
}
)