我有一個帶有陣列值的物件,我想在這種情況下從中提取我想要的數字:
首先,我應該檢查陣列中的數字是升序還是降序,所以如果它們是其中之一,則回傳它們,但如果它們不是,請檢查:
如果陣列中的資料是從一個特定的號碼開始像1或2或1000以及一個單元,每次添加有特殊的圖案,像1, 0, 0, 2, 0, 0, 3, 0, 0或1000, 10, 1001, 20, 1002, 30,..可以提取它們之間的數字(它們也應是連續的),例如:如果這是陣列
[1, 300, 400, 2, 500, 650, 3, 800, 1130],
輸出應該是這樣的:[300, 400, 500, 650, 800, 1130],
或者,如果這是陣列:
[4, 60, 5, 50, 6, 40.3],
輸出應該是這樣的: [60, 50, 40.3]
所以它并不重要多少元件在之間1和2在第一陣列或4和5在第二陣列,但如果有3層之間的元件1和2,而且3個元素應介于3和4,以及數字它們之間應該是連續的,(在第一個陣列中,您可以看到數字是升序的,而在第二個陣列中,數字是降序的。所以在這里我們希望每次增加 1 個單位的數字之間的連續數字)。
如果不滿足任何條件,只需為每個不滿足條件的 Object.value 回傳一個空陣列。
更多細節 :
這是我的代碼,我嘗試撰寫代碼,但我不知道如何查找數字并在它們之間推送連續的數字元素并推送到新陣列,我只能檢查陣列中的升序或降序數字。
const numbers : {
number1 : [1, 300, 2, 400, 3, 500, 4, 600, 5, 800],
number2 : [0, 1.1, 1, 1.2, 2, 1.3, 3, 1.4],
number3 : [2, 1000, 3, 980, 4, 700, 5,100, 6, 10],
number4 : [1000, 1001, 1001.3, 1003, 1014],
number5 : [34, 76, 0, 50, 0.5, 1010, 0.5],
};
//The output I want :
// {
// number1 : [300, 400, 500, 600, 800],
// number2 : [1.1, 1.2, 1.3, 1.4],
// number3 : [1000, 980, 700, 100, 10],
// number4 : [1000, 1001, 1001.3, 1003, 1014],
// number5 : []
// };
const res = {}
for(var i=0, i < Object.values(numbers).length, i ){
el = Object.values(number)[i];
if (consecutive(el) == true) {
res[Object.keys(numbers)[i]] = el;
}else{
//check and find numbers that added one unit and extract numbers between them.
}
}
//This function check if numbers are consecutive or not, for consecutive numbers in array returns the last element and for non-consecutive numbers returns false.
const consecutive = (param) => {
let res = param.reduce((prev , next) => {
if(prev < next) {
if(prev == false) {
return prev
}
return next;
}else{
return false;
}
})
return (typeof res == 'number')
}
那么如何找到每次添加一個單位的數字并將它們洗掉并將它們推送到新陣列?
uj5u.com熱心網友回復:
在我看來,您想要一個演算法來定義您的陣列是否每個值都有一個成對的索引。我認為要走的路是獲取所有奇數,然后查看它們是否以 1 為單位遞增。如果是,那么您的陣列是一個索引值對。
const numbers= {
number1: [1, 300, 2, 400, 3, 500, 4, 600, 5, 800],
number2: [0, 1.1, 1, 1.2, 2, 1.3, 3, 1.4],
number3: [2, 1000, 3, 980, 4, 700, 5,100, 6, 10],
number4: [1000, 1001, 1001.3, 1003, 1014],
number5: [34, 76, 0, 50, 0.5, 1010, 0.5],
}
function getEvenNumbers(arr) {
return arr.filter((n,i) => i % 2 )
}
function getOddNumbers(arr) {
return arr.filter((n,i) => (i 1) % 2 )
}
function isIndexed(arr) {
for(let i=1; i < arr.length; i ) {
if ( arr[i] !== (arr[i-1] 1) ) return false
}
return true
}
function valuesOnly(arr) {
return isIndexed(getOddNumbers( arr )) ? getEvenNumbers(arr) : arr
}
console.log( 'number1', valuesOnly(numbers.number1) )
console.log( 'number2', valuesOnly(numbers.number2) )
console.log( 'number3', valuesOnly(numbers.number3) )
console.log( 'number4', valuesOnly(numbers.number4) )
console.log( 'number5', valuesOnly(numbers.number5) )
結果是:
number1 [300, 400, 500, 600, 800]
number2 [1.1, 1.2, 1.3, 1.4]
number3 [1000, 980, 700, 100, 10]
number4 [1000, 1001, 1001.3, 1003, 1014]
number5 [34, 76, 0, 50, 0.5, 1010, 0.5]
uj5u.com熱心網友回復:
我建議使用一個單獨的函式來檢查輸入陣列是否是單調的(全部降序或全部升序)。
如果輸入不是單調的,需要一些繁瑣的檢查,但思路是找到起始值 1的位置。如果找到,那么你就知道間隙大小,可以通過跳轉驗證這個序列的其余部分通過該間隔的陣列,您還可以收集中間值。如果跳轉練習確認“分隔符”值都以 1 遞增,那么您可以使用第一段中提到的函式檢查收集的中間值是否是單調的。
存在第二個值出現多次的邊界情況,并且存在不止一種可能性。情況就是這樣[1,0,2,2,3,4]。它可以分解為以下任何一種:
[1,[0],2,[2],3,[4]]=>[0,2,4],或[1,[0,2],2,[3,4]]=>[0,2,3,4]
在這種情況下,下面的解決方案將有利于第一個解決方案。改變這種行為很容易。
代碼:
function monotone(numbers) { // Return argument when it is all increasing/decreasing, else []
if (numbers.length < 2) return numbers;
let inc = numbers[1] - numbers[0];
for (let i = 2; i < numbers.length; i ) {
if ((numbers[i] - numbers[i-1]) * inc <= 0) return [];
}
return numbers;
}
function extract(numbers) {
let test = monotone(numbers);
// We're done when input is all ascending or descending
if (test.length == numbers.length) return numbers;
let start = numbers[0];
let gap = numbers.indexOf(start 1);
while (gap > 0) {
if (numbers.length % gap == 0) {
collect = [];
for (let j = 0, expect = start; j < numbers.length && numbers[j] === expect; j = gap, expect ) {
collect.push(...numbers.slice(j 1, j gap));
}
if (collect.length === numbers.length - (numbers.length / gap)) {
collect = monotone(collect);
if (collect.length) return collect;
}
}
gap = numbers.indexOf(start 1, gap 1);
}
return monotone(numbers);
}
const numbers = {
number1 : [1,300,2,400,3,500,4,600,5,800],
number2 : [0,1.1,1,1.2,2,1.3,3,1.4],
number3 : [2,1000,3,980,4,700,5,100,6,10],
number4 : [1000,1001,1001.3,1003,1014],
number5 : [34 , 76 , 0 , 50 , 0.5 , 1010 , 0.5],
trincot: [1,0,2,2,3,4]
};
const result = Object.fromEntries(
Object.entries(numbers).map(([key, numbers]) => [key, extract(numbers)])
);
console.log(result);
uj5u.com熱心網友回復:
下面提供的通用解決方案滿足 OP 的所有要求。
實作代碼背后的方法基于兩個輔助函式。
第一個計算一系列數字值的最長位置串列,其中每個值要么遞增要么遞減 value 1,但既不是直接前因也不是另一個匹配數字值的直接后繼。
第二個助手檢測嚴格單調的數字序列,以便在沒有數字序列的情況下回傳正確的結果,其中每個數字值都以有效的方式分隔其他陣列項。
function isStrictlyMonoton(arr) {
const diff = arr[0] - arr[1];
const isStrict = ((diff < 0)
&& ((a, b) => a < b)) || ((diff > 0)
&& ((a, b) => a > b)) || false;
return !!isStrict && arr.every((val, idx, arr) => (idx === 0)
? isStrict(val, arr[idx 1])
: isStrict(arr[idx - 1], val)
)
}
function collectSeparatingOneBasedSeriesPositionList(listOfSeries, number, idx, arr) {
const series = [idx];
let recentIdx = idx;
while (
(idx = arr.indexOf((number = number 1), (idx 2))) > recentIdx
) {
recentIdx = idx;
series.push(idx);
}
listOfSeries.push(series);
return listOfSeries;
}
function removeSeparatingOneBasedNumberSeriesValues(arr) {
if (Array.isArray(arr)) {
// compute the longest position list of a series of number
// values which are either incremented or decremented by
// the value 1, but do separate other array items, thus are
// not direct antecessors/successors itself.
const baseIdx = arr.length - 1;
const longestSeriesPositionList = arr
.reduce(collectSeparatingOneBasedSeriesPositionList, [])
.concat(
// shallow copy in order to not mutate the original reference.
[...arr]
.reverse()
.reduce(collectSeparatingOneBasedSeriesPositionList, [])
// re-map/sanitize position values due to the initial `reverse` call.
.map(positionList => positionList.reverse().map(idx => baseIdx - idx))
).sort((a, b) => b.length - a.length)[0];
if (longestSeriesPositionList.length >= 2) {
const positionLookup = Object.fromEntries(
longestSeriesPositionList.map(idx => [idx, true])
);
arr = arr.filter((_, idx) => !(idx in positionLookup));
} else if (!isStrictlyMonoton(arr)) {
arr = [];
}
}
return arr;
}
Object
.entries({
number_1: [1, 300, 2, 400, 3, 500, 4, 600, 5, 800],
number_2: [0, 1.1, 1.2, 1, 1.3, 1.4, 2],
number_3: [2, 1000, 3, 980, 4, 700, 5, 100, 6, 10],
number_4: [1000, 1001, 1001.3, 1003, 1014],
number_5: [34, 76, 0, 50, 0.5, 1010, 0.5],
pilchard: [1, 20, 30, 40, 50, 2],
trincot_A: [1, 1, 2, 2, 3, 4],
trincot_B: [1, 0, 2, 2, 3, 4],
})
.forEach(([key, value]) => {
console.log(
`${ key } ... [${ value }] => [${ removeSeparatingOneBasedNumberSeriesValues(value) }]`
);
console.log(
`${ key }/reversed ... [${ [...value].reverse() }] => [${ removeSeparatingOneBasedNumberSeriesValues([...value].reverse()) }]`
);
});
.as-console-wrapper { min-height: 100%!important; top: 0; }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/336679.html
標籤:javascript 节点.js 数组
