newbeedev
newbeedev

Reputation: 19

Searching key value pair match and sort array

I'm a beginner in Javascript, and I'm trying to sort an array after finding a key value from that array, For example:

    var users = [
        { 'user': 'fred', 'age': 48 },
        { 'user': 'barney', 'age': 49},
        { 'user': 'fred1', 'age': 50 },
        { 'user': 'barney1', 'age': 51 },
        { 'user': 'barney2', 'age': 55 },
        { 'user': 'fred2', 'age': 56 },
        { 'user': 'barney3', 'age': 57 },
        { 'user': 'fred3', 'age': 58 },
        { 'user': 'barney4', 'age': 59 },
        { 'user': 'fred4', 'age': 60 },
    ];

Here in this array, First i would like to find user with value fred3 and then rearrange array by putting fred3 as first element, like below

 var users = [
        { 'user': 'fred3', 'age': 58 },
        { 'user': 'fred', 'age': 48 },
        { 'user': 'barney', 'age': 49},
        { 'user': 'fred1', 'age': 50 },
        { 'user': 'barney1', 'age': 51 },
        { 'user': 'barney2', 'age': 55 },
        { 'user': 'fred2', 'age': 56 },
        { 'user': 'barney3', 'age': 57 },
        { 'user': 'barney4', 'age': 59 },
        { 'user': 'fred4', 'age': 60 },
    ];

First element should be searched key value pair. I am using lodash for this, i tried like

_.map(users, item =>{
    let searchedItem = this.isThisItem(item) ? item : null;
     // This searchedItem may be null also

    let Other = return _.reject(users, item=>{
       return searchedItem.value === item.value;
    })
            //here i want to do sort
}),

isThisItem(item){
   // Logic here to match item with other data, if it exist it returns true.                   
}

Can anyone Help me to finish it? Thanks in advance.

Upvotes: 0

Views: 3128

Answers (3)

matts
matts

Reputation: 298

map is not the right tool here. The function you pass as the second argument will be executed on each element of the array in order, and can't be used to re-order the array. It's better if you want to transform a collection of one thing into a collection of another thing. For example, say you wanted to change your collection of objects into a collection of just the user names from each object - map is what you want.

The other solutions already posted should work perfectly well; but if you really want to use lodash you can do something like this:

var users = [
    { 'user': 'fred', 'age': 48 },
    { 'user': 'barney', 'age': 49},
    { 'user': 'fred1', 'age': 50 },
    { 'user': 'barney1', 'age': 51 },
    { 'user': 'barney2', 'age': 55 },
    { 'user': 'fred2', 'age': 56 },
    { 'user': 'barney3', 'age': 57 },
    { 'user': 'fred3', 'age': 58 },
    { 'user': 'barney4', 'age': 59 },
    { 'user': 'fred4', 'age': 60 }
];

var split = _.partition(users, {'user': 'fred3'});
console.log(split);

var result = split[0].concat(split[1]);
console.log(result);

(Here is the above on JSBin)

partition takes an array and splits it into two arrays based on a predicate - a function that takes one argument and returns true or false. In this case, we split it into the arrays "objects which are 'fred3'" and "objects which are not 'fred3'". Then we just take those two arrays and join them together with the "objects which are 'fred3'" at the front.

The second argument to partition is very flexible; I used a shorthand from the lodash docs here but you can pass a regular predicate function (like your isThisItem(item) { ... }) instead.

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386654

A solution in plain Javascript.

  1. Search for the given user and
  2. Splice the array at the index and insert it at the beginning of the array.

var users = [{ 'user': 'fred', 'age': 48 }, { 'user': 'barney', 'age': 49 }, { 'user': 'fred1', 'age': 50 }, { 'user': 'barney1', 'age': 51 }, { 'user': 'barney2', 'age': 55 }, { 'user': 'fred2', 'age': 56 }, { 'user': 'barney3', 'age': 57 }, { 'user': 'fred3', 'age': 58 }, { 'user': 'barney4', 'age': 59 }, { 'user': 'fred4', 'age': 60 }, ];

function moveToTop(user, users) {
    users.some(function (a, i) {
        if (a.user === user) {
            users.unshift(users.splice(i, 1)[0]);
            return true;
        }
    });
}

moveToTop('fred3', users);
document.write('<pre>' + JSON.stringify(users, 0, 4) + '</pre>');

Or direct with sorting

var users = [{ 'user': 'fred', 'age': 48 }, { 'user': 'barney', 'age': 49 }, { 'user': 'fred1', 'age': 50 }, { 'user': 'barney1', 'age': 51 }, { 'user': 'barney2', 'age': 55 }, { 'user': 'fred2', 'age': 56 }, { 'user': 'barney3', 'age': 57 }, { 'user': 'fred3', 'age': 58 }, { 'user': 'barney4', 'age': 59 }, { 'user': 'fred4', 'age': 60 }, ],
    user = 'fred3';

users.sort(function (a, b) {
    return (a.user === user || a.age) - (b.user === user || b.age);
});

document.write('<pre>' + JSON.stringify(users, 0, 4) + '</pre>');

Upvotes: 1

Rajesh
Rajesh

Reputation: 24925

You can use array.filter to remove the searched object. Then you can sort using custom sort function and then using unshift, you can prepend value to array.

var users = [
        { 'user': 'fred', 'age': 48 },
        { 'user': 'barney', 'age': 49},
        { 'user': 'fred1', 'age': 50 },
        { 'user': 'barney1', 'age': 51 },
        { 'user': 'barney2', 'age': 55 },
        { 'user': 'fred2', 'age': 56 },
        { 'user': 'barney3', 'age': 57 },
        { 'user': 'fred3', 'age': 58 },
        { 'user': 'barney4', 'age': 59 },
        { 'user': 'fred4', 'age': 60 },
    ];
  
  var searchName = "fred3"
  var searchedObj = users.filter(function(item){
    return item.user === searchName;
  })[0];
  
  var result = users.filter(function(item){
    return (item.user !== searchName);
  }).sort(function(a,b){
    return a.age - b.age;
  });
  
  result.unshift(searchedObj);
  
  console.log(result)

Upvotes: 1

Related Questions