0

I'm trying to find a way to move an object to the end of the array

I have this array of objects:

[
  {"id":"4","name":"Boaz"},
  {"id":"2","name":"Shareen"},
  {"id":"3","name":"Simon"},
  {"id":"1","name":"Miriam"}
]

I want to move the whole set {"id":"3","name":"Simon"} to the end of it all. I have solution for this here. But my problem is every time that particular object is not coming in second position is there a way to check the object of id=3 and shift that to end using underscoreJS

Community
  • 1
  • 1
Shrinivas Pai
  • 7,491
  • 4
  • 29
  • 56
  • 1
    Have you tried anything? I'm not sure what you've tried that is causing the problem. – 4castle Feb 27 '17 at 06:27
  • Possible duplicate of [Move object in array to end](http://stackoverflow.com/questions/24562280/move-object-in-array-to-end) – brightDot Feb 27 '17 at 06:29

7 Answers7

8

You can just sort array.

Explanation

Array.sort expects 3 possible values as return value.

  • 1: means a is greater than b and a will be move to a higher index than b
  • 0: means a is equal to b and no change will be made.
  • -1: means a is less than b and a will be move to a lower index than b.

For more information please refer: How does Javascript's sort() work?

var data = [
  {"id":"4","name":"Boaz"},
  {"id":"2","name":"Shareen"},
  {"id":"3","name":"Simon"},
  {"id":"1","name":"Miriam"}
]

data.sort(function(a,b){
  return a.id == 3 ? 1 : 0
})

console.log(data)

An alternate method could to filter out objects with necessary id, remove them from current position and the push them back, but this is too much work in my understanding. Sort is ideal way to move object up or down the order.

Community
  • 1
  • 1
Rajesh
  • 24,354
  • 5
  • 48
  • 79
  • can you explain what `return a.id == 3 ? 1 : 0`? didn't downvote – madalinivascu Feb 27 '17 at 06:37
  • 2
    I don't think this answers his question, he is looking for something that moves the element with id: 3 to the end. yours would not work for something like [{id:3},{id:4}]. edit: in fact yours does not move the element with id: 3 to the end of the array. – Elliot E Feb 27 '17 at 06:38
  • @Rajesh my mistake, you are correct, I misread your sort condition. Apparently I can't change to an upvote unless you edit your answer... Maybe you could add a period to your last sentance ;) edit: upvoted – Elliot E Feb 27 '17 at 06:47
  • I just saw your answer and deleted my answer :p – Fareed Alnamrouti Feb 27 '17 at 06:56
  • Basically in sort function for every element in the array as "a" if you return 1 "a" will move up and if you return -1 it will move down and 0 will not affect the array "b" is the next element so you can compare with – Fareed Alnamrouti Feb 27 '17 at 06:57
  • See: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort – Fareed Alnamrouti Feb 27 '17 at 07:06
  • from the description "If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this." – Fareed Alnamrouti Feb 27 '17 at 07:07
  • No sort is working like reduce function if "a" replaced with "b" then it becomes the next "a" again in the 2nd call and if not "b" becomes the next "a" there is huge difference – Fareed Alnamrouti Feb 27 '17 at 07:15
  • you don't respect `b.id === '3'`, your sort is not symetrically. – Nina Scholz Feb 27 '17 at 07:32
  • @NinaScholz if `b` is `3` no change should happen. So adding `a.id==3 ? 1 : b.id==3?0:0` looked an overkill. Though I accept your point. – Rajesh Feb 27 '17 at 07:37
  • 1
    your sort fails on `var data = [ {"id":"4","name":"Boaz"}, {"id":"3","name":"Simon"}, {"id":"2","name":"Shareen"}, {"id":"1","name":"Miriam"} ]` – Nina Scholz Feb 27 '17 at 07:41
  • @NinaScholz `id:3` is still last. [JSFiddle](https://jsfiddle.net/RajeshDixit/p3gLdvv5/). Sorry if I'm not getting your point. Please feel free to edit/downvote if there is some major shortfall in code. – Rajesh Feb 27 '17 at 07:47
  • please try your sorting with my above posted array with edge. – Nina Scholz Feb 27 '17 at 07:51
  • 1
    I think @NinaScholz is right and we are both wrong every browser or environment may use deferent sorting algorithm for deferent case the JavaScrip let you defines the behaviour of the compare function, not how the actual sort is implemented. – Fareed Alnamrouti Feb 27 '17 at 08:02
3

Do some simple array manipulation

var obj = [{
    "id": "4",
    "name": "Boaz"
  },
  {
    "id": "2",
    "name": "Shareen"
  },
  {
    "id": "3",
    "name": "Simon"
  },
  {
    "id": "1",
    "name": "Miriam"
  }
];
obj.forEach(function(v, i) {
  if (v.id == 3) {//test to see if the id is 3
    obj.push(obj[i]);//push the object to the last position
    obj.splice(i, 1);//remove the object from the current position

  }

});
console.log(obj);
madalinivascu
  • 32,064
  • 4
  • 39
  • 55
3

I suggest to use the delta of the comparison, not only if you have more than one true comparison, but you need a symetrically comparison, if b contains the item to sort at the end, then you get the order, you want.

var array = [{ id: "4", name: "Boaz" }, { id: "2", name: "Shareen" }, { id: "3", name: "Simon" }, { id: "1", name: "Miriam" }];

array.sort(function (a, b) {
    return (a.id === '3') - (b.id === '3');
});

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

While there isnt an "out-of-the-box" underscore function, we can extend the base library with our own function using the _.mixin() function.

The extension works by using the underscore _.indexOf() function to return the index of an element that matches a predicate. We then use the native JS splice function, to remove 1 item at the returned index (Note that this will leave the array unaffected if _.indexOf returns -1). As per the docs, splice, returns an array of all elements that were removed. We, lastly use the native JS concat function, which merges two (or more) arrays together, to put the returned value from the concat on to the end of the supplied array (arr).

UnderscoreJS extending

(function(_) {
    "use strict";
    _.mixin({
        moveToEndWhere: moveToEndWhere
    });

    /**
     * @function moveToEndWhere
     * @desc Searches an array for the first item matching a predicate, and moves the matched element to the end of the array
     * @param {array} arr Array to be searched and altered
     * @param {function|object} predicate Function or object used to search for matching element
     * @returns {array} Updated array
     * @memberof _.mixin
     */
    function moveToEndWhere(arr, predicate){
        return arr.concat(
            arr.splice(
                _.indexOf(arr, predicate)
                , 1
            )
        );
    }
})(_);

Usage

var data = [
    {"id":"4","name":"Boaz"},
    {"id":"2","name":"Shareen"},
    {"id":"3","name":"Simon"},
    {"id":"1","name":"Miriam"}
];

data = _.moveToEndWhere(data, {"id":3});
haxxxton
  • 6,422
  • 3
  • 27
  • 57
0
function findIdIndex(id, array) {
  return array.findIndex(elem=>elem.id===id);
}

This will give you the position of the set with the given id, the answer to your previous question covers the rest of what you want to do.

Elliot E
  • 452
  • 3
  • 14
0

first write a method like this,send the value as '3' and get the index and attr as id

function getElementIndex(array, attr, value) {
    for(var i = 0; i < array.length; i += 1) {
        if(array[i][attr] === value) {
            return i;
        }
    }
    return -1;
}

By this method you can use any property to get the data with.

Then write

var index=getElementIndex(array,'id','3');//here array is your data array you have 
var itemToReplace = array.splice(index, 1); 

array = array.concat(itemToReplace);
Viplock
  • 3,259
  • 1
  • 23
  • 32
0

Can you try this with the getting index of the respective object and then check the position:

var array  = [{ "id": "4", "name": "Boaz" }, { "id": "2", "name": "Shareen" }, { "id": "3", "name": "Simon" }, { "id": "1", "name": "Miriam" }];

var index =  array.findIndex(x => x.id == 3);

if(index === 2) {
 var person =  array.splice(index, 1);
 array  = array.concat(person);
}

console.log(array)
Rajesh
  • 24,354
  • 5
  • 48
  • 79
Ganesh
  • 52
  • 6