Reputation: 111
Here's my code:
var myArr = [1,2,3,4,5];
function queue(arr, item) {
return arr.push(item).shift();
}
I'm attempting to create a function queue which takes an "array" and an "item" as arguments. I need to
My code is not working. Can you help me figure this out?
Upvotes: 9
Views: 6335
Reputation: 26086
push
[1, 2].concat([3])
// [1,2,3]
shift
[1,2,3].filter((e, i, a) => i != 0)
// [2,3]
pop
[1,2,3].filter((e, i, a) => i != a.length - 1)
// [1,2]
unshift
[1,2,3].concat([0]).map((e, i, a) => i == 0 ? a[a.length - 1] : a[i-1])
// [0,1,2,3]
Using the 2nd param index and 3rd param array inside map and filter makes things pretty flexible. You can try more by using that approach.
Another (easier) way but slightly reckless and NOT immutable
push
Array.prototype.pushChain = function(item) {
this.push(item)
return this
}
[1,2,3].pushChain(4)
//[1,2,3,4]
Meaning you can use the prototype of an array and use the simpler methods you want to chain but simply return this
and you are good but the downside is you could mess up other code relying on the Array to be as it is or possibly overriding some other method you didn't intend.
OR
Another approach is make a JavaScript ES6+ type class like so
class ImmutableChainedArray {
constructor(arr) {
this._arr = Array.isArray(arr) ? arr : []
}
push(item) {
this._arr = this._arr.concat([item])
return this
}
pop() {
this._arr = this._arr
.filter((e, i, a) => i != a.length - 1)
return this
}
shift() {
this._arr = this._arr
.filter((e, i, a) => i != 0)
return this
}
unshift(item) {
this._arr = this._arr
.concat([item])
.map((e, i, a) => i == 0 ? a[a.length - 1] : a[i-1])
return this
}
// the rest of them are easy...
val() {
return this._arr
}
}
then use like
const ica = new ImmutableChainedArray([1])
ica.unshift(0).push(2).shift().pop().val()
// ends up with [1]
Upvotes: 3
Reputation: 32572
Actually, all answers are right and I wanna just add another way in ES6
:
const Queue = (array, item) => { array.push(item); return array.splice(0,1); }
Or
const Queue = (array, item) => { array.push(item); return array.shift(); }
You shouldn't use concat
instead of push
because in your case you should mutate your myArr
array because it is a queue.
Upvotes: 1
Reputation: 6444
There is sort of a hack using concat
instead of push
function queue(arr, item) {
return arr.concat([item]).shift();
}
Should get you the result you want.
Upvotes: 2
Reputation: 288590
Just don't chain the method calls:
function queue(arr, item) {
arr.push(item);
return arr.shift();
}
Or, if you want a single statement,
function queue(arr, item) {
return arr.push(item), arr.shift();
}
Alternatively, if you are mad enough, you could subclass Array and add a chainable push:
class MyArray extends Array {
chainablePush(item) {
this.push(item);
return this;
}
}
var myArr = new MyArray(1,2,3);
myArr.chainablePush(4).shift(); // 1
myArr; // MyArray [2,3,4];
Upvotes: 13
Reputation: 1
because arr.push returns the length of the array, you can't chain the shift like that
simply do this
function queue(arr, item) {
arr.push(item);
return arr.shift();
}
Upvotes: 8