1

I thought I could use

$ [1,2,3,4,5].splice((this.length / 2), 1)[0]

but it gives me

$ 1 

I tried

$ [1,2,3,4,5].splice(function() { return this[this.length / 2, 1]})

but it gives me

[ 1, 2, 3, 4, 5 ]

I'm looking for a solution that gives me an integer and for even arrays is the lower of the two, e.g.

[1,2,3,4] givees 2
[1,2,3,4,5] gives 3
[1,2,3,4,5,6] gives 3
[1,2,3,4,5,6,7] gives 4
Michael Durrant
  • 93,410
  • 97
  • 333
  • 497
  • 2
    please add the wanted result – Nina Scholz Aug 21 '20 at 08:33
  • 3
    `splice` doesn’t accept functions. `splice` _mutates_ the array and returns an array containing the deleted elements. See [the documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice). What is the `$` at the beginning of your code blocks? – Sebastian Simon Aug 21 '20 at 08:33
  • 1
    What do you want exactly as output? An array? Could you clarify your question? I though you wanted the middle element? – João Pimentel Ferreira Aug 21 '20 at 08:37
  • What if the array has an even number of elements? – ihodonald Aug 21 '20 at 09:08
  • Does this answer your question? [finding Middle element of an array in javascript](https://stackoverflow.com/questions/36254254/finding-middle-element-of-an-array-in-javascript) – jonrsharpe Aug 21 '20 at 09:57
  • Also https://stackoverflow.com/q/20904368/3001761, https://stackoverflow.com/q/50425313/3001761 - please do research before asking (and if you have done it, please show it in the question). – jonrsharpe Aug 21 '20 at 09:59
  • Thanks as always Jon. I hoped to accept the others answer to mark mine as dupe but when I tried it out I had issues using it. Also my requirements were unclear so I updated them. – Michael Durrant Aug 21 '20 at 10:10
  • @MichaelDurrant my answer works on the test cases you provided. – Majed Badawi Aug 21 '20 at 10:18
  • *"when I tried it out I had issues using it"* - then give a [mre]. As an experienced user you should be doing as [ask] suggests by default. – jonrsharpe Aug 21 '20 at 14:45

6 Answers6

1

The issue is with this reference. Try this:

console.log(getMiddle([1,2,3,4]));
console.log(getMiddle([1,2,3,4,5]));
console.log(getMiddle([1,2,3,4,5,6]));
console.log(getMiddle([1,2,3,4,5,6,7]));

function getMiddle(arr){
     return arr.splice(Math.floor((arr.length-1) / 2), 1)[0]
}

However, As @jonrsharpe 's comment states, splicing a single-element array from an index to the same index plus one then getting the first value in the result creates a redundant array. A better way to get the middle element would be the following:

console.log(getMiddle([1,2,3,4]));
console.log(getMiddle([1,2,3,4,5]));
console.log(getMiddle([1,2,3,4,5,6]));
console.log(getMiddle([1,2,3,4,5,6,7]));

function getMiddle(arr){
     return arr[Math.floor((arr.length - 1) / 2)];
}
Majed Badawi
  • 27,616
  • 4
  • 25
  • 48
  • 1
    I would delete the first suggestion entirely - splicing a single-element array from an index to the same index plus one then getting the first value in the result creates a redundant array, the second is much neater. – jonrsharpe Aug 21 '20 at 14:43
  • @jonrsharpe Yes the second one is neater, but the first is just to solve the OP problem in the used method. I added some explanations tho. Thanks for the comment. – Majed Badawi Aug 21 '20 at 15:21
0

You cannot use this as a parameter because this is supposed to be called inside functions, whereas splice accept as parameters integers. If you really want to use this you may use a prototype. Use Math.floor function since arrays indexes only accept integers, and Math.floor rounds up to the lowest integer (ex: Math.floor(2.5) === 2).

Array.prototype.getMiddle = function () {
  return this[Math.floor(this.length/2)]
}

console.log([1,2,3,4,5].getMiddle()) // 3

The above function only works when the length of the array is an odd number, since arrays whose length is an even number do not have "middle" element.

If you want to check if the array has a middle

Array.prototype.getMiddle = function () {
  return (this.length % 2) ? this[Math.floor(this.length/2)] : null
}

console.log([1,2,3,4,5].getMiddle()) // 3
console.log([1,2,4,5].getMiddle()) // null

Alternative solutions:

var arr = [1,2,3,4,5]

var middleEl = arr[Math.floor(arr.length/2)] 

console.log(middleEl) // 3

If you want to use splice

var arr = [1,2,3,4,5]

var middleEl = arr.splice((arr.length / 2), 1)[0]

console.log(middleEl)

If you want a function

console.log(middleEl([1,2,3,4,5])) //3
console.log(middleEl([1,2,4,5])) //null

function middleEl (arr) {
   return (arr.length % 2) ? arr[Math.floor(arr.length/2)] : null
}
João Pimentel Ferreira
  • 14,289
  • 10
  • 80
  • 109
  • @user4642212 ok, ok, the result is the same, but you're right, parseInt is made for converting strings to integers, but they also round up number. – João Pimentel Ferreira Aug 21 '20 at 08:41
  • @user4642212 the questions says `How to select the middle of an array?`. What am I reading wrong? Am I supposed to be an expert in hermeneutics? – João Pimentel Ferreira Aug 21 '20 at 08:47
  • @user4642212 whatever, I give you now four different ways of calculating, explaining why you can't use `this` with splice, since splice only accepts integers as parameters, even presenting a prototype wherein you can use `this`. I hope now it suffices. – João Pimentel Ferreira Aug 21 '20 at 09:09
0

You should use something like that.

var data, remaining, hold, result;
data = ["1","2","3","4","5","6","7","8", "9"];
remaining = data.length % 2;
hold = Math.floor(data.length / 2);
result = data[(remaining + hold - 1)];
document.write(result);
0
let arr = [ 1, 2, 3, 4, 5 ]
let len = arr.length;
let mid = Math.floor(len / 2);
console.log(arr[mid]);
// or
console.log(arr.slice(mid, mid + 1));

or if you want the middle two, you can do mid + 2 using a var that tests to see if the length is even.

Marcell Toth
  • 3,433
  • 1
  • 21
  • 36
ihodonald
  • 745
  • 1
  • 12
  • 27
  • or if you want the middle two, you can do `mid + 2` using a var that tests to see if the length is even. – ihodonald Aug 21 '20 at 09:14
0

You could create a prototype for getting the middle element/s.

Array.prototype.middle = function () {
    const
        half = this.length >> 1,
        offset = 1 - this.length % 2;
    
    return this.slice(half - offset, half + 1);
};

console.log([1, 2, 3, 4, 5].middle());    // [3]
console.log([1, 2, 3, 4, 5, 6].middle()); // [3, 4]
console.log([1, 2, 3, 4].middle());       // [2, 3]
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Why not simply, assuming a.length > 0:

const a = [1, 2, 3, 4, 5]
console.log(a[(a.length - 1) >> 1])
const b = [1, 2, 3, 4, 5, 6]
console.log(b[(b.length - 1) >> 1])

I think this should be a fairly fast way of doing it. The >> operator is an integer shift, which divides the number by two - ignoring decimals.

Jørgen Tvedt
  • 1,214
  • 3
  • 12
  • 23