So I have an array of objects;
[
{
"foo": 2,
"bar": "test"
},
{
"foo": 19,
"bar": "value"
},
{
"foo": 7,
"bar": "temp"
}
]
I need to move an object with a particular value of foo
to the beginning of the array. The value is always in the object, but there's no guarantee the object will be in the array.
So after running moveToFront(19);
for instance, I'd have the following:
[
{
"foo": 19,
"bar": "value"
},
{
"foo": 2,
"bar": "test"
},
{
"foo": 7,
"bar": "temp"
}
]
How would I go about doing this?
So I have an array of objects;
[
{
"foo": 2,
"bar": "test"
},
{
"foo": 19,
"bar": "value"
},
{
"foo": 7,
"bar": "temp"
}
]
I need to move an object with a particular value of foo
to the beginning of the array. The value is always in the object, but there's no guarantee the object will be in the array.
So after running moveToFront(19);
for instance, I'd have the following:
[
{
"foo": 19,
"bar": "value"
},
{
"foo": 2,
"bar": "test"
},
{
"foo": 7,
"bar": "temp"
}
]
How would I go about doing this?
Share Improve this question edited Feb 22, 2019 at 14:11 vsync 130k59 gold badges340 silver badges421 bronze badges asked Jan 11, 2016 at 18:58 Emphram StavangerEmphram Stavanger 4,2149 gold badges38 silver badges66 bronze badges 6- there may be a better data structure then an array, what are your requirements/ what are you trying to do? depending on how often you need to move things around this array and how large it is this could get expensive quick. – James Commented Jan 11, 2016 at 19:03
- why? what are you trying to do that makes you think you need to move elements in the array at all? – Mike 'Pomax' Kamermans Commented Jan 11, 2016 at 19:04
- What's the purpose of the object being in the front of the array? – Kyle Pittman Commented Jan 11, 2016 at 19:04
- stackoverflow.com/questions/5306680/… – gurvinder372 Commented Jan 11, 2016 at 19:04
- 1 The value is always in the object, but there's no guarantee the object will be in the array. Huh? – Matt Burland Commented Jan 11, 2016 at 19:05
5 Answers
Reset to default 15This should be fairly trivial, you search your array until you find the item you are looking for then you splice
it out and unshift
it back to the beginning. Something like this:
// foo is the target value of foo you are looking for
// arr is your array of items
// NOTE: this is mutating. Your array will be changed (unless the item isn't found)
function promote(foo, arr) {
for (var i=0; i < arr.length; i++) {
if (arr[i].foo === foo) {
var a = arr.splice(i,1); // removes the item
arr.unshift(a[0]); // adds it back to the beginning
break;
}
}
// Matching item wasn't found. Array is unchanged, but you could do something
// else here if you wish (like an error message).
}
If there is no item with a matching foo
value, then this will do nothing to your array. You can handle that with an error message if desired.
Shortest way: Array.some
The
some()
method tests whether at least one element in the array passes the test implemented by the provided function. It returns a Boolean value.
Note that Array.find
also breaks the iteration once target is found, but it isn't' supported on IE.
var data = [{"foo":2}, {"foo":19}, {"foo":7}, {"foo":22}]
// if {foo:7} is found, move it to the front and break iteration
data.some((item, idx) =>
item.foo == 7 &&
data.unshift(
// remove the found item, in-place (by index with splice),
// returns an array of a single item removed
data.splice(idx,1)[0]
)
)
// print result
console.log(data)
If you don't want to mutate the original Array, you can do:
var data = [{"foo":2}, {"foo":19}, {"foo":7}, {"foo":22}]
// if {foo:7} is found, move it to to the front and break iteration
const clonedData = [...data]
clonedData.some((item, i, arr) => item.foo == 7 && arr.unshift(item))
// print result
console.log(clonedData)
findIndex method will be helpful
The
findIndex()
method returns the index of the first element in the array that satisfies the provided testing function. Otherwise, it returns -1, indicating that no element passed the test.var data = [{"foo":2}, {"foo":19}, {"foo":7}, {"foo":22}] // find the index of the target array item: var itemIndex = data.findIndex(item => item.foo == 7); data.splice( 0, // new index, 0, // no removal data.splice(itemIndex, 1)[0] // detach the item and return it ); // print result console.log(data)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
If you use lodash and need to have legacy browsers support, use the
_.findIndex
method:
_.findIndex(data, {foo:19});
This will move the Array Object with the key "foo": 19
to the beginning of the array.
You can iterate the array, find the right element, splice it and concat the rest of the array to the spliced array.
var collection = [
{
foo: 15,
bar: true
},
{
foo: 19,
bar: false
}
];
function moveToFront(x) {
for (var i = 0; i < collection.length; i++) {
if (collection[i].foo === x) {
collection = collection.splice(i, 1).concat(collection);
break;
}
}
}
moveToFront(19);
console.log(collection);
Search any value in every property, first match wins. It seems to be very fast because of using method 'some' and breaking the iteration over tha array if the condition is met.
'some' executes the callback function once for each element present in the array until it finds one where callback returns a true value. If such an element is found, some() immediately returns true. Mutation is in place ...
var collection = [
{
"foo": 2,
"bar": "test"
},
{
"foo": 19,
"bar": "value"
},
{
"foo": 7,
"bar": "temp"
}
];
function moveToFront(searchValue) {
var idx, exists;
for (idx = 0; idx < collection.length; idx++) {
exists = Object.keys(collection[idx]).some(function (key) {
return collection[idx][key] === searchValue
});
if (exists) break;
}
collection.unshift(collection[idx]);
collection.splice(idx + 1, 1);
}
moveToFront("temp"); // or moveToFront(19); or move whatever
console.log(collection);
Yet another solution. Mutation in place ...
var collection = [
{
"foo": 2,
"bar": "test"
},
{
"foo": 19,
"bar": "value"
},
{
"foo": 7,
"bar": "temp"
}
];
function moveToFront(property, value, col) {
col.reduce(function (prev, current, idx, obj) {
if (current[property] != value) {
return obj;
} else {
obj.unshift(obj[idx]);
obj.splice(idx + 1, 1);
}
});
}
moveToFront('foo', 7, collection);
console.log(collection);