我需要从中间词语中查看数组。
var array = [a,b,c,d,e];
我需要按此顺序打印: C,d,B,E,A
我已经将数组分成两半,先是向前然后向后移动,这已经是一个改进了,但我真的需要在每一侧都进行一次,直到每一侧的阵列结束。
说我想从中间开始。我在循环语句之前有以下条件,条件,我似乎无法弄清楚第三部分逐渐切换每一侧的一个。
for (var i = Math.floor(array.length/2); i >= 0 || i < array.length; i?){
//Do Something here.
}
有谁知道怎么做? 显然我似乎无法在这种情况下测试这一点。
由于
我修改了the answer below(非常感谢)来提出这个功能。它允许从阵列中的任何位置开始并选择要去的方向。我相信它可以写得更优雅。错误的索引号也有安全性。
var array = ["a", "b", "c", "d", "e"];
function processArrayMiddleOut(array, startIndex, direction){
if (startIndex < 0){
startIndex = 0;
}
else if ( startIndex > array.length){
startIndex = array.lenght-1;
};
var newArray = [];
var i = startIndex;
if (direction === 'right'){
var j = i +1;
while (j < array.length || i >= 0 ){
if (i >= 0) newArray.push(array[i]);
if (j < array.length) newArray.push(array[j]);
i--;
j++;
};
}
else if(direction === 'left'){
var j = i - 1;
while (j >= 0 || i < array.length ){
if (i < array.length) newArray.push(array[i]);
if (j >= 0) newArray.push(array[j]);
i++;
j--;
};
};
return newArray;
}
var result = processArrayMiddleOut(array, 2, 'left');
alert(result.toString());
答案 0 :(得分:8)
两个柜台,一个上升,另一个上下:
var array = ["a", "b", "c", "d", "e"];
var newArray = [];
var i = Math.ceil(array.length/2);
var j = i - 1;
while (j >= 0)
{
newArray.push(array[j--]);
if (i < array.length) newArray.push(array[i++]);
}
答案 1 :(得分:2)
所以我决定重温这一点,对我给出的第一个答案并不满意。我很肯定当数据成功重新排序时,索引号之间会有一些关系;我在最后一个项目位置添加了迭代编号的模式。
对于我们的初始数组,我们将使用以下内容:['a', 'b', 'c', 'd', 'e']
。
我们的起点是Math.floor( arr.length / 2 )
,它给出了2
,对应于数组值中的c
。这是迭代0
。以下说明详细说明了我们如何遍历具有奇数个值的数组:
Position | Direction | Iteration | New Position | Value at Position
----------+-----------+-----------+--------------+-------------------
2 | - | 0 | 2 | c
2 | + | 1 | 3 | d
3 | - | 2 | 1 | b
1 | + | 3 | 4 | e
4 | - | 4 | 0 | a
你会看到一个模式正在发展,当我们的迭代是奇数时,我们将它添加到我们的位置以找到我们的新位置。当迭代为负数时,我们从我们的位置减去它以找到新位置。
处理具有偶数个值的数组时,将翻转规则。当你有一个偶数个值时,我们从位置中减去奇数迭代以获得新位置,并将迭代添加到我们的位置以找到下一个值。
为了演示执行此排序逻辑需要多少代码,下面是上述逻辑的缩小版本(前面提到的链接更具可读性):
// DON'T USE THIS IN PRODUCTION, OR YOUR TEAM MAY KILL YOU
function gut(a){
var o=[],s=a.length,l=Math.floor(s/2),c;
for(c=0;c<s;c++)o.push(a[l+=(s%2?c%2?+c:-c:c%2?-c:+c)]);
return o
}
以更易读的方式实现上述逻辑:
// Sort array from inside-out [a,b,c,d,e] -> [c,d,b,e,a]
function gut( arr ) {
// Resulting array, Counting variable, Number of items, initial Location
var out = [], cnt,
num = arr.length,
loc = Math.floor( num / 2 );
// Cycle through as many times as the array is long
for ( cnt = 0; cnt < num; cnt++ )
// Protecting our cnt variable
(function(){
// If our array has an odd number of entries
if ( num % 2 ) {
// If on an odd iteration
if ( cnt % 2 ) {
// Move location forward
loc = loc + (+cnt);
} else {
// Move location backwards
loc = loc + (-cnt);
}
// Our array has an even number of entries
} else {
// If on an odd iteration
if ( cnt % 2 ) {
// Move location backwards
loc = loc + (-cnt);
} else {
// Move location forwards
loc = loc + (+cnt);
}
}
// Push val at location to new array
out.push( arr[ loc ] );
})()
// Return new array
return out;
}
答案 2 :(得分:1)
好的,让我们一步一步解决这个问题:
(array.length - 1) / 2
。将此索引称为mid
。mid
个元素。明显。mid
个元素。array.length / 2
。将此索引称为mid
。mid
个元素。明显。mid - 1
个元素。现在让我们使用上述已知数据创建一个解决此问题的函数:
function processMidOut(array, callback) {
var length = array.length;
var odd = length % 2; // odd is 0 for an even number, 1 for odd
var mid = (length - odd) / 2; // succinct, isn't it?
callback(array[mid]); // process the middle element first
for (var i = 1; i <= mid; i++) { // process mid number of elements
if (odd || i < mid) // process one less element if even
callback(array[mid + i]); // process the right side element first
callback(array[mid - i]); // process the left side element next
}
}
这就是它的全部。现在让我们创建一些数组并在中间处理它们:
var odd = ["a", "b", "c", "d", "e"];
var even = ["a", "b", "c", "d", "e", "f"];
var oddOrder = "";
var evenOrder = "";
processMidOut(odd, function (element) {
oddOrder += element;
});
processMidOut(even, function (element) {
evenOrder += element;
});
alert(oddOrder);
alert(evenOrder);
您可以在此处找到有效的演示:http://jsfiddle.net/xy267/1/
答案 3 :(得分:1)
非常有趣的算法。这就是我的意思:
walkMidleOut = function(arr, callback) {
var mid = (arr.length - arr.length % 2) / 2;
for (var i = 0; i < arr.length; i++) {
var s = -1,
j = (i % 2 ? (s = 1, i + 1) : i) / 2,
index = mid + s * j == arr.length ? 0 : mid + s * j;
callback.call(arr, arr[index], index);
}
}
用法:
walkMidleOut([1,2,3,4,5], function(el, index) {
console.log(el, index);
});
会给你:
3 2
4 3
2 1
5 4
1 0
函数可以与任意数量的元素一起使用,奇数或偶数。
答案 4 :(得分:1)
如何使用concat()
和slice()
?你可以把它传递给中间元素的索引。
Array.prototype.eachFrom = function(index){
var index = index > this.length ? 0 : index;
return [].concat(this.slice(index), this.slice(0, index));
}
所以例如:
var arr = ['a', 'b', 'c', 'd', 'e'], arr = arr.eachFrom(2);
for( var i = 0; i < arr.length; i++ ) { doFunThings(); }
答案 5 :(得分:0)
使用underscore和_(对象).Sort_Inside_Out():
_.mixin( {
Sort_Inside_Out: function ( Object ) {
Counter = 0
return (
_( Object ).sortBy( function ( Element ) {
Counter =
-Counter + (
( Math.sign( Counter ) == 1 ) ?
0 :
1 )
return ( Counter )
} ) )
},
} )
答案 6 :(得分:0)
这是从数组中的任何索引开始并同时向前和向后循环的一种简单方法(即,对所有从最接近索引的项开始并远离索引的项进行迭代)。
let passing = 0;
function bothSides(arr, idx) {
newArr = [];
const shortLen = Math.min(idx, arr.length - idx);
for (let i = 0; i < shortLen; i++) {
newArr.push(arr[idx + i]); // add next
newArr.push(arr[idx - i - 1]); // add previous
}
for (let i = idx + shortLen; i < arr.length; i++) {
newArr.push(arr[i]); // add any remaining on right
}
for (let i = idx - shortLen - 1; i > -1; i--) {
newArr.push(arr[i]); // add any remaining on left
}
return newArr;
}
var arr = [...Array(10).keys()]; // 0,1,2,3,4,5,6,7,8,9
passing += bothSides(arr, 0) == '0,1,2,3,4,5,6,7,8,9' ? 1 : 0;
passing += bothSides(arr, 2) == '2,1,3,0,4,5,6,7,8,9' ? 1 : 0;
passing += bothSides(arr, 4) == '4,3,5,2,6,1,7,0,8,9' ? 1 : 0;
passing += bothSides(arr, 5) == '5,4,6,3,7,2,8,1,9,0' ? 1 : 0;
passing += bothSides(arr, 7) == '7,6,8,5,9,4,3,2,1,0' ? 1 : 0;
passing += bothSides(arr, 9) == '9,8,7,6,5,4,3,2,1,0' ? 1 : 0;
// same algorigthm but as generator
function* bothSidesG(arr, idx) {
const shortLen = Math.min(idx, arr.length - idx);
for (let i = 0; i < shortLen; i++) {
yield arr[idx + i]; // add next
yield arr[idx - i - 1]; // add previous
}
for (let i = idx + shortLen; i < arr.length; i++) {
yield arr[i]; // add any remaining on right
}
for (let i = idx - shortLen - 1; i > -1; i--) {
yield arr[i]; // add any remaining on left
}
}
var arr2 = [...Array(7).keys()]; // 0,1,2,3,4,5,6
passing += [...bothSidesG(arr2, 0)] == '0,1,2,3,4,5,6' ? 1 : 0;
passing += [...bothSidesG(arr2, 1)] == '1,0,2,3,4,5,6' ? 1 : 0;
passing += [...bothSidesG(arr2, 3)] == '3,2,4,1,5,0,6' ? 1 : 0;
passing += [...bothSidesG(arr2, 5)] == '5,4,6,3,2,1,0' ? 1 : 0;
passing += [...bothSidesG(arr2, 6)] == '6,5,4,3,2,1,0' ? 1 : 0;
console.log(`Passing ${passing} of 11 tests`);