I have an object, let's say
var obj = [{"name": "banana", "type": "fruit"},
{"name": "carrot", "type": "vegetable"}];
And I need to add an object right after the first one [0] so I'll get the following:
var obj = [{"name": "banana", "type": "fruit"},
{"name": "apple", "type": "fruit"},
{"name": "carrot", "type": "vegetable"}];
needless to say I want it dynamic, and I'm trying to avoid loops for ease of use later down the road...
Is there any function like
obj.pushAfter(this['type'], "fruit", {"name": "apple", "type": "fruit"});
Type of function? P.S I'm using Jquery so that's an option
I have an object, let's say
var obj = [{"name": "banana", "type": "fruit"},
{"name": "carrot", "type": "vegetable"}];
And I need to add an object right after the first one [0] so I'll get the following:
var obj = [{"name": "banana", "type": "fruit"},
{"name": "apple", "type": "fruit"},
{"name": "carrot", "type": "vegetable"}];
needless to say I want it dynamic, and I'm trying to avoid loops for ease of use later down the road...
Is there any function like
obj.pushAfter(this['type'], "fruit", {"name": "apple", "type": "fruit"});
Type of function? P.S I'm using Jquery so that's an option
Share Improve this question asked May 20, 2016 at 13:07 gal zakaygal zakay 1052 silver badges9 bronze badges5 Answers
Reset to default 2While the accepted answer is informative and leads you to the right direction, if you are actually in need if a pushAfter
function that does exactly what you described, you could roll your own like so...
function pushAfter(coll, k, v, add) {
var matchIndex = coll.reduce(function(prevVal, currVal, i, arr) {
if (currVal[k] === v) {
return i;
}
});
coll.splice(matchIndex + 1, 0, add);
}
var obj = [{"name": "banana", "type": "fruit"},
{"name": "carrot", "type": "vegetable"}];
pushAfter(obj, 'type', "fruit", {"name": "apple", "type": "fruit"});
pushAfter(obj, 'name', "carrot", {"name": "radish", "type": "vegetable"});
This would yield:
[{
name: "apple",
type: "fruit"
}, {
name: "banana",
type: "fruit"
}, {
name: "carrot",
type: "vegetable"
}, {
name: "radish",
type: "vegetable"
}]
This finds your specified key and value within the given collection and splices in the new item at the matched index. Leveraging reduce
in this case also provides a simple way to identify the match's index. Additionally, here's a working example.
First off, your talking about pushing into an array, not an object. The two are different animals, and it's important you understand their differences.
What you want is the splice function on the native array object. arr.splice(index, 0, item); will insert item into arr at the specified index.
Source: How to insert an item into an array at a specific index?
Documentation: https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
var obj = [{"name": "banana", "type": "fruit"},
{"name": "carrot", "type": "vegetable"}];
// splice(position, numberOfItemsToRemove, item)
obj.splice(1, 0, {"name": "apple", "type": "fruit"});
You could a function for it. It searches for the right property key
and insert the item after the group, before other groups have started.
This solution features Array#some
, because it stops iterating if the wanted index is found.
function pushAfter(array, key, item) {
var index = 0;
array.some(function (a, i) {
if (a[key] === item[key]) {
index = i + 1;
return false;
}
return index;
});
array.splice(index, 0, item);
}
var array = [{ "name": "banana", "type": "fruit" }, { "name": "carrot", "type": "vegetable" }];
pushAfter(array, 'type', { "name": "apple", "type": "fruit" });
console.log(array);
Doing a sorted push will only work if the array is already sorted correctly, so if you always start with an empty or sorted array and the array is only mutated by the pushAfter
function, then you're fine. However, if you retrieve the array from an external API, it can be modified outside of your pushAfter
function, or you are otherwise unable to guarantee that the array will always be sorted before you push to it, you can't guarantee that a pushAfter
function will always provide a sorted array.
For example, if you start with an array with objects sorted in the order of fruit, fruit, vegetable, fruit
, the above pushAfter
function will result in the array sorted as fruit, fruit, vegetable, fruit, fruit
instead of fruit, fruit, fruit, fruit, vegetable
. A method that will always be reliable would be to do a regular push
and then sort
the array.
function sortedPush(sourceArray, newObject) {
sourceArray.push(newObject);
sourceArray.sort(function(a, b) {
// returns 0 if both objects have equal type
// 1 if a is greater than b (should be sorted after)
// -1 if a is less than b (should be sorted before)
return (a.type === b.type) ? 0 : a.type > b.type;
});
}
var unsortedArray = [{
"name": "banana",
"type": "fruit"
}, {
"name": "carrot",
"type": "vegetable"
}, {
"name": "grape",
"type": "fruit"
}];
sortedPush(unsortedArray, {
"name": "orange",
"type": "fruit"
});
console.log(unsortedArray);
unsortedArray
after the sorted push:
[{
name: "banana",
type: "fruit"
}, {
name: "grape",
type: "fruit"
}, {
name: "orange",
type: "fruit"
}, {
name: "carrot",
type: "vegetable"
}]
Demo
See documentation for Array.sort