Javascript 从数组中检索均匀分布的元素数
我知道如何提取数组中的每个第n项,但我遇到的困难如下: 如何从1800个元素的数组中提取第n个元素,始终包括第一个和最后一个元素,总共256个元素 例如:Javascript 从数组中检索均匀分布的元素数,javascript,arrays,Javascript,Arrays,我知道如何提取数组中的每个第n项,但我遇到的困难如下: 如何从1800个元素的数组中提取第n个元素,始终包括第一个和最后一个元素,总共256个元素 例如: array = [1,2,3,4,5,6,7,8,9,10]; // Set up an array for testing purposes var items = []; for (var i=1; i<= 1800; i++) { items.push(i); } var extracted = distributed
array = [1,2,3,4,5,6,7,8,9,10];
// 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);
摘录5个要素:
extract = [1,3,5,7,10];
基本答案是写作
array.filter(filterFunc)
其中,对参数为elt
、index
和array
的每个元素调用filterFunc
,并应返回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)
像这样吗
/**
* 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;
}
/**
*从数组中检索固定数量的元素,均匀分布,但
*始终包括第一个和最后一个元素。
*
*@param{Array}items-要操作的数组。
*@param{number}n-要提取的元素数。
*@returns{Array}
*/
功能分发副本(项,n){
变量元素=[项目[0]];
var totalItems=items.length-2;
var区间=数学下限(总项目/(n-2));
对于(变量i=1;i
例如:
array = [1,2,3,4,5,6,7,8,9,10];
// 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);
//为测试目的设置一个数组
var项目=[];
对于(var i=1;ii),我稍微改善了先前的反应
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]
函数evenlyPickItemsFromArray(allItems:T[],neededCount:number){
//如果我们想要的物品多于可用物品,请退回所有物品
如果(neededCount>=所有项目长度){
返回[…allItems];
}
//用于收集拾取项目的缓冲区
常数结果:T[]=[];
const totalItems=所有项目长度;
//项目之间的默认间隔(可能是浮动)
const interval=总项目数/所需计数;
for(设i=0;ii);
}
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))//[33100166]
请注意,它不是每次都选择第一个/最后一个元素,因为它实际上相当复杂-例如,如果我选择1个元素-我应该选择第一个还是最后一个等。它只是找到均匀分布并选择它们。只有当您需要输入数组中的所有或几乎所有元素时,才会选择第一个和最后一个元素。算法@pie6k的可视化演示
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>
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>')
}
}
)
elementsInArray=365
neededCountElementsInArray=234
函数createNLongArray(n){
返回数组.from({length:n}).map((z,i)=>i+1);
}
函数均匀选取项数组(所有项、所需计数){
如果(neededCount>=所有项目长度){
返回[…所有项目]
}
常量结果=[]
const totalItems=所有项目长度
const interval=totalItems/neededCount
for(设i=0;i$('.js chartData').append(''+i+'')
elementsSave=evenlyPickItemsFromArray(数组,neededCountElementsInArray)
console.log(elementsSave)
array.map(i=>{
if(要素附件包括(i)){
$('.js chartResult')。追加(''+i+'')
}否则{
$('.js chartResult')。追加(''+i+'')
}
}
)
其余254个项目是如何确定的?随机的吗?这有关系吗?你可以提取255个第一个项目并追加最后一个项目。如果你能给我们足够的信息,我们可以帮助你,否则我们猜测。或者中间的那些被提取在“每一个n”。basis?当你说提取时,你是从数组中删除元素还是只是复制它们?另外,在你的示例中,你不是像你说的那样检索最后一个元素。如果你的提取数组是从原始数组中提取的元素,你就没有提取最后一个元素。因此,结果似乎与你所看到的不一样ing for,因为根据您的问题,您需要包括第一个和最后一个项目。刚刚注意到这只返回227个项目,而不是256@jokerstream是的,你是对的,随着数字越来越大,四舍五入出现问题。试试更新的版本。哇。这正是我在google sea几个小时后想要的rching.请注意,您是在循环之前计算floor'ing间隔,而不是在每次迭代中(Math.floor(rawInterval*i)
)。因此,如果间隔为1.8(例如,从180个长数组中选取100个元素),实际间隔将为1,因此您将主要从数组的前半部分拾取元素。我添加了改进的解决方案有时太接近阈值var test=新数组(14)。填充('a')。映射((项,I)=>item+I)测试。筛选(makeFilterFunc(3))
/[“a0”、“a4”、“a8”、“a12”、“a13”]a12和a13太接近