开发者

Compacting arrays in JavaScript

What is JavaScript equivalent to Ruby's Array#compact?

Long version.... I followed the examples at blog.nemikor.com. His last example closes out old requests, but then pendings continues to be filled with obsolete requests. This looks like a memory leak to me.

My solution is to iterate over pendings with filter as below, but this seems like there may be a race condition between pendings.push and pendings = pendings.filter. Am I being paranoid? If a race condition exists, how should I fix it?

var pendings = [];

// there is a route
app.get('/some/path', function (request, response) {
  pendings.push({
    response: response,
    requestedAt: new Date().getTime()
  });
});

setInterval(function () {
  var expiration = new Date().getTime() - (1000 * 30);
  pendings = pendings.filter(function (pending, index) {
    if (pending.requestedAt > expiration) {
   开发者_如何学JAVA   return true;
    } else {
      pending.response.writeHead(408, { 'Content-Type': 'text/plain' });
      pending.response.end('');
    }
  });
}, 1000);


You have no threads in JavaScript, so there can be no race condition. All code is sequenced and will transfer control only after it's done running. So your interval function will run till completion before any other function is going to touch pendings.

This holds for things like setTimeout and setInterval.

As an experiment: If you made a timeout using setTimeout to fire after 1 second. And after that you write a while-loop that blocks for 2 seconds, your timeout will fire after that, so much longer than 1 second.

Something crude:

var timer = setTimeout(function () {
    alert("hi!");
}, 1000);
var now = new Date();
var till = new Date(now + 2);
while(new Date() < till) {}   // block for 2 seconds


You may want to take a look at the Underscore.js library
http://documentcloud.github.com/underscore/

This provides many useful low-level functions to deal with collections, arrays and objects. It includes both a compact function (though I think it serves a different purpose to what you're looking for) and a filter function.


An old thread but it deserves an answer to the original question:

What is JavaScript equivalent to Ruby's Array#compact?

list1 = [null, 'no', 'nulls', null]

// With plain JS
jsFilter = list1.filter(function (obj) { return obj })

// With ES6
let filtered = list1.filter((obj) => obj)

//> (2) ["no", "nulls"]

console.log(es6Filter)

But there is a caveat, because:

filter() calls a provided callback function once for each element in an array and constructs a new array of all the values for which callback returns a value that coerces to true.

falsey = [false, 0, 0n, '', NaN, null, undefined]
truthy = [true, 1, ' ']

list2 = ['returns', 'only', 'truthy', 'values'].concat(truthy).concat(falsey)

let filtered = list2.filter((obj) => obj)

//> (7) ["returns", "only", "truthy", "values", true, 1, " "]

console.log(filtered)

In order to have it working like Ruby's compact, you can do:

falsey = [false, 0, 0n, '', NaN, null, undefined]
truthy = [true, 1, ' ']
list3 = ['works', 'like', "Ruby's", 'compact'].concat(truthy).concat(falsey)

let them_go = [null, undefined] // Just a fun with variable names
let filtered = list3.filter((obj) => { return !them_go.includes(obj) })

//> (12) ["works", "like", "Ruby's", "compact", true, 1, " ", false, 0, 0n, "", NaN]

console.log(filtered)

If you want to remove all the empty elements (empty Strings, Arrays, and Objects) from an array, you can check my answer here -> https://stackoverflow.com/a/59905255/3251051

References:

  • https://ruby-doc.org/core-2.6.5/Array.html#method-i-compact
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
  • https://developer.mozilla.org/en-US/docs/Glossary/Falsy
  • https://developer.mozilla.org/en-US/docs/Glossary/Truthy
  • http://kenglish.co/blog/2018/1/remove-null-elements-from-array-with-javascript


As long as you're not doing I/O, i.e., you are only doing in-memory operations, you are guaranteed to not be interrupted (due to the nature of the event loop).

Being so, be careful, if your collection is too long (like on the thousands or more), because you can block the event loop for some time, not letting the other requests be serviced.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜