0

if I have a big collection of array, what is the fastest way to sort and return the first 5 items?

Array of Object:

[
  {
    "name" : "placeA",
    "menus" : [ 
        {
            "sold" : 5,
            "name" : "menuA"
        }, 
        {
            "sold" : 20,
            "_id" : "menuB"
        }, 
        {
            "sold" : 1000,
            "_id" : "menuC"
        }
    ]
  },
  {
    "name" : "placeB",
    "menus" : [ 
        {
            "sold" : 300,
            "name" : "menuD"
        }, 
        {
            "sold" : 400,
            "_id" : "menuE"
        }, 
        {
            "sold" : 50,
            "_id" : "menuF"
        }
    ]
  },
  {
    "name" : "placeC",
    "menus" : [ 
        {
            "sold" : 1500,
            "name" : "menuG"
        }, 
        {
            "sold" : 450,
            "_id" : "menuH"
        }, 
        {
            "sold" : 75,
            "_id" : "menuI"
        }
    ]
  }
]

Expected Output:

[
    {
      "sold" : 1500,
      "name" : "menuG"
    },
    {
      "sold" : 1000,
      "_id" : "menuC"
    },
    {
      "sold" : 450,
      "_id" : "menuH"
    },
    {
      "sold" : 400,
      "_id" : "menuE"
    },
    {
      "sold" : 300,
      "name" : "menuD"
    } 
]

The only possible way that I'm able to think of is to create an array that is filled all the menus and then sort the menus and then slice the first 5 items. I don't think this way is good enough for sorting a huge collection of array in real use case.

0

3 Answers 3

2

You can use .map(), .reduce(), .concat(), .sort(), and .slice().

var arr = [{
    "name": "placeA",
    "menus": [{
        "sold": 5,
        "name": "menuA"
      },
      {
        "sold": 20,
        "_id": "menuB"
      },
      {
        "sold": 1000,
        "_id": "menuC"
      }
    ]
  },
  {
    "name": "placeB",
    "menus": [{
        "sold": 300,
        "name": "menuD"
      },
      {
        "sold": 400,
        "_id": "menuE"
      },
      {
        "sold": 50,
        "_id": "menuF"
      }
    ]
  },
  {
    "name": "placeC",
    "menus": [{
        "sold": 1500,
        "name": "menuG"
      },
      {
        "sold": 450,
        "_id": "menuH"
      },
      {
        "sold": 75,
        "_id": "menuI"
      }
    ]
  }
]

var newarr = arr.map(v => v.menus).reduce((a, c) => a.concat(c));
console.log(newarr.sort((a,b) => b.sold - a.sold).slice(0,5));

I'm not sure if this is the fastest way, though.

Sign up to request clarification or add additional context in comments.

Comments

1

You can use .reduce(), and clean it up with spread operator to flatten the Arrays as you go, and destructing to get straight to the 'menus' Array

const data = [{name:"placeA",menus:[{sold:5,name:"menuA"},{sold:20,_id:"menuB"},{sold:1e3,_id:"menuC"}]},{name:"placeB",menus:[{sold:300,name:"menuD"},{sold:400,_id:"menuE"},{sold:50,_id:"menuF"}]},{name:"placeC",menus:[{sold:1500,name:"menuG"},{sold:450,_id:"menuH"},{sold:75,_id:"menuI"}]}];

let newArray = data
  .reduce((acc, {menus}) => [...acc, ...menus], [])
  .sort((a, b) => b.sold - a.sold);

console.log(newArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

1

In addition to what Yousername said, you can also you flat :

array
.map((a) => a.menus) // select menus
.flat() // all sub-array elements concatenated
.sort((a, b) => b.sold - a.sold) // sort by key sold
.slice(0,5) // select the first 5

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.