最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to sort array in nodejs based on file size? - Stack Overflow

programmeradmin3浏览0评论

I have an array with names of files as the entities of the array. I wanted to sort this array based on the size of the files.

For example,

var arr=['index.html','README.md','index.html']; 

So what I currently have is that I create an object with name of files as key and size of file as the value.

Now I am fetching these files from a remote location, so I can get the size of the file from content-length header.

Is there a better way to do it? Will it be possible to do this locally by which I mean read file size and create an object based on that?

I have an array with names of files as the entities of the array. I wanted to sort this array based on the size of the files.

For example,

var arr=['index.html','README.md','index.html']; 

So what I currently have is that I create an object with name of files as key and size of file as the value.

Now I am fetching these files from a remote location, so I can get the size of the file from content-length header.

Is there a better way to do it? Will it be possible to do this locally by which I mean read file size and create an object based on that?

Share Improve this question edited May 21, 2016 at 13:00 Michał Perłakowski 92.9k30 gold badges163 silver badges187 bronze badges asked Jan 11, 2016 at 7:15 Harkirat SalujaHarkirat Saluja 8,1245 gold badges52 silver badges74 bronze badges 1
  • If you have an object with "name of files as key and size of file as the value" then you can't sort it because Javascript doesn't provide any API for changing the object property order. – Tomáš Zato Commented Jan 11, 2016 at 7:32
Add a ment  | 

4 Answers 4

Reset to default 4

Try this:

var arr = ['index.html','README.md','index.html'];

arr.sort(function(a, b) {
  return fs.statSync(a).size - fs.statSync(b).size;
});

I assume that these files are in your current directory.

Short memoized version without promises:

var arr = ['index.html', 'README.md', 'index.html'];
var sortedArray = arr
    // get the size of each file
    .map(file => { return { file: file, size: fs.statSync(file).size } })
    // sort by size ascending
    .sort((a, b) => a.size > b.size)
    // return a simple sorted array of the file names only
    .map(f => f.file);

console.log(sortedArray);

using Bluebird promise, I would do it something like:

var Bluebird = require('bluebird'),
  fs = Bluebird.promisifyAll(require('fs')),
  arr = [
     // your file array
  ];

// retriving size of each file
function getSize(file){
    return fs.statAsync(file).then(stats => stats.size);
}

Promise.all(arr.map( file=> getSize(file).then(size=> {return {file, size}})))
  .then(sizedArry => {
    console.log(sizedArry);
    var sortedArray = sizedArry.sort((a, b) => a.size > b.size); // sorting array based on size
    console.log('sorted array: ', sortedArray);
    // if you want only the sorted file names...
    return sortedArray.map(element => element.file);
  });

Expanding on @Gothdo's answer:

var fs = require('fs');
var arr = ['index.html','README.md','index.html'];

function memoize(func) {
  var cache = {};

  // assumes argument is string
  return function memoized(str) {
    if (cache[str]) return cache[str];

    return (cache[str] = func(str));
  };
}

var statSync = memoize(fs.statSync);

arr.sort(function sort(a, b) {
  return statSync(a).size - statSync(b).size;
});

Memoizing the function should improve performance of the sorting algorithm, which is quicksort in node, last time I checked.

发布评论

评论列表(0)

  1. 暂无评论