Utilize Ramda to selectively filter each inner property within arrays

I have a data structure that looks like this:

const arrays = {
  one: [[1, 33, 41], [2, 0, 27], [3, 7, 9], [4, 1, 3]],
  two: [[1, 77, 2], [2, 6, 3], [3, 0, 0], [4, 55, 3]],
  three: [[1, 4, 6], [2, 0, 0], [3, 5, 6], [4, 0, 0]],
};

In this structure, the first number in each array is consistent:
1 for the first inner array, 2 for the second inner array, 3 for the third inner array, and so on.

I am looking to filter these arrays based on the first number and a comparison number (e.g. [3]).
For example, if we use the filter number [3] (less than or equal to 3), the desired result would be:

const arrays = {
  one:   [[1,33,41], [2,0,27], [3,7,9]],
  two:   [[1,77,2],  [2,6,3],  [3,0,0]],
  three: [[1,4,6],   [2,0,0],  [3,5,6]],
};

This output includes only the inner arrays where the first numbers are less than or equal to 3, while ignoring those starting with higher numbers like 4, 5, and so on. What would be the Ramda approach to achieve this functionality?

Answer №1

I appreciate how Ramda's map function allows for seamless iteration over object properties without the need for Object.fromEntries or Object.entries. This function embodies the power of filter, which takes inner arrays as arguments. The filter function is a clever composition of gte and head, comparing the first element of each array to 3:

const arrays =
  { one:   [[1, 33, 41], [2, 0, 27], [3, 7, 9], [4,  1, 3]]
  , two:   [[1, 77,  2], [2, 6,  3], [3, 0, 0], [4, 55, 3]]
  , three: [[1,  4,  6], [2, 0,  0], [3, 5, 6], [4,  0, 0]] };

   map(filter(compose(gte(3), head)), arrays);
// ^   ^      ^       ^       ^
// A   B      C       D       E

//=> { one:   [[ 1, 33, 41], [2, 0, 27], [3, 7, 9]]
//=> , two:   [[ 1, 77,  2], [2, 6,  3], [3, 0, 0]]
//=> , three: [[ 1,  4,  6], [2, 0,  0], [3, 5, 6]] }
  • Mapping over each property (A) sends each array to filter (B)
  • Each inner array then undergoes compose (C)
  • The head of each inner array is compared with 3 (D)

A helpful note from Scott Christopher in the comments about gte being tricky when partially applied. Simplifying the entire composition, we can replace it with this concise lambda: ([x]) => x <= 3.

Another solution that I find appealing:

map(filter(([x]) => x <= 3), arrays);

Answer №2

I am in full agreement with @customcommander's method, and I would like to mention that numerical indexes can also be passed to R.propSatisfies.

const headIs3OrBelow = R.propSatisfies(R.gte(3), 0);
const fn = R.map(R.filter(headIs3OrBelow));

// ===
const data = {
  one: [[1, 33, 41], [2, 0, 27], [3, 7, 9], [4, 1, 3]],
  two: [[1, 77, 2], [2, 6, 3], [3, 0, 0], [4, 55, 3]],
  three: [[1, 4, 6], [2, 0, 0], [3, 5, 6], [4, 0, 0]],
};

console.log(
  fn(data),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>


I also concur that gte and similar methods are challenging to read, as they seem to read backwards like is 3 gte than x... In Haskell, you could express this as:


3 `gte` x

A more straightforward approach:

const headIs3OrBelow = ([head]) => head <= 3;

const fn = (data) => Object.entries(data).reduce(
  (res, [k, lists]) => ({ ...res, [k]: lists.filter(headIs3OrBelow) }),
  {},
);

// ===
const data = {
  one: [[1, 33, 41], [2, 0, 27], [3, 7, 9], [4, 1, 3]],
  two: [[1, 77, 2], [2, 6, 3], [3, 0, 0], [4, 55, 3]],
  three: [[1, 4, 6], [2, 0, 0], [3, 5, 6], [4, 0, 0]],
};

console.log(
  fn(data),
);

Answer №3

While I see your interest in utilizing Ramda, here is an alternative approach that achieves the same outcome without relying on the library. In this solution, we create an object called from entries where the entries are filtered based on comparing the first array value a[0] with the specified maxVal.

const arrays = {
  one: [[1, 33, 41], [2, 0, 27], [3, 7, 9], [4, 1, 3]],
  two: [[1, 77, 2], [2, 6, 3], [3, 0, 0], [4, 55, 3]],
  three: [[1, 4, 6], [2, 0, 0], [3, 5, 6], [4, 0, 0]],
};

const filterArrays = (arsObj, maxVal) => {
  return Object.fromEntries(Object.entries(arsObj).map(([k, v]) => {
    return [k, v.filter((a) => a[0] <= maxVal)];
  }));
}

const result = filterArrays(arrays, 3);
console.log(result);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue encountered while retrieving information using Axios in a Vue.js application

Currently, I am in the process of developing a full stack application using Vue.js and Fastify.js (a Node framework). The Vue app is supposed to retrieve data from the API I created and display it in the browser console. However, I am encountering an issue ...

What is the process for consolidating a TypeScript web application with node modules into a single JavaScript file using the command line

How can I efficiently set up a TypeScript web application with all node modules compiled into one JavaScript file for use in HTML? If my project structure looks like this: ├── node_modules │ └── mathjs │ └── (dependencies, etc.) ...

The inclusion of Bootstrap 4 in the header seems to be causing issues with mouse events not functioning correctly

Exploring the functionalities of Bootstrap 4 and jQuery has been an interesting journey. I recently worked on creating a Navbar with 4 links, where the 4th link has a submenu that opens upon hover. However, I encountered an issue where this functionality o ...

Tips for emphasizing the letters of the alphabet used in search functionality with Angular

Is there a way to highlight specific alphabets in the searched list instead of highlighting the entire word? Currently, when filtering the memberOffice and memberFacilities lists based on the alphabet entered in the search field, the entire text is highlig ...

Looking through a Json file and retrieving data with the help of Javascript

I am currently working on developing a dictionary application for FirefoxOS using JavaScript. The structure of my JSON file is as follows: [ {"id":"3784","word":"Ajar","type":"adv.","descr":" Slightly turned or opened; as, the door was standing ajar.","tr ...

Guide on sending a post request to a PHP component

var table = $('#accessRequest').DataTable({ "dom": 'Blfrtip', "ajax": "Editor-PHP-1.5.1/php/editor-serverside.php", "columns": [ { //special column for detail view ...

Transforming a tag string into an array

When working with a string of tags that are separated by spaces, inconsistencies in spacing can occur due to user input. In the code snippet below, I intentionally added multiple spaces for demonstration. $somestring = "<h1> <a> <h5> & ...

Ensure that clicking on an element closes any currently visible elements before opening a new element

Take a look at my code snippet below. I am working on creating multiple clickable divs that reveal different content when clicked. However, the issue I am facing is that currently, both content blocks can be displayed simultaneously. My goal is to have onl ...

Is it feasible to swap out the cursor for a personalized image of my choice?

Can I replace the cursor icon with my own custom image that I created in Photoshop? I have seen websites with custom cursor images, so I know it is possible. But how do I do it and is it a standard approach? Will it work across all browsers? ...

Error encountered with Firebase Modular SDK V9.0.0+: Issue with undefined firebase property 'apps' causing TypeError

Encountered an error while attempting to run my next.js app. Despite trying various methods, I have been unable to resolve it. The version of Firebase I am using is 9.0.1 Server Error TypeError: Cannot read property 'apps' of undefined The error ...

Steer clear of initializing arrays in Java

Can the need for array zeroing/initialization in Java be avoided? I have a requirement to rapidly create new byte arrays of a specific length that will be filled with predetermined data. This means I do not need the JVM to automatically zero out the array ...

Is there a quicker way to locate information by using keyword search?

I am currently facing the task of searching for every occurrence of "Parameters Table" within a string array, and then extracting another string from a specific index between each instance. The approach I have been using is as follows: public List<stri ...

Tips for composing a single aggregation within a query

In my query, I wanted to find the first record with a CREATE_DATE greater than or equal to a specific date and less than another date. After calculating the duration between these dates, I needed to write another query. However, I was unsure how to combine ...

Simple steps to change JSON Object to JavaScript array

Referring to this question and this other one, I am seeking advice on how to handle a JSON object structure different from the examples provided: This is my JSON Object: var myData = { "04c85ccab52880": { "name": "name1", "firstname": ...

When making an Axios API request in Next.js, an error is encountered stating that the property 'map' cannot be read as it is undefined

Hey there! I've been trying to fetch data from the API endpoint in my NextJs application using axios. However, whenever I try to map over the retrieved data, NextJs keeps throwing the error message "TypeError: Cannot read property 'map' of ...

Angular 6: Issue with displaying data on the user interface

Hello! I am attempting to fetch and display a single data entry by ID from an API. Here is the current setup: API GET Method: app.get('/movies/:id', (req, res) => { const id = req.params.id; request('https://api.themoviedb.org/ ...

Enhancing the appearance of a variety of React elements

Is there a way to apply inline styling to an array of React Components without directly adding the height to the 'ProductComponent'? I would like to add "height:33%" to the parent div of each component in the array. I want to achieve this within ...

Exploring ways to retrieve information stored in localStorage within an android mobile application

I am currently developing an Android App using phonegap. The app is a simple game that generates random numbers for math problems. If the user answers correctly, their score increases, but if they lose, their name and current score are saved in localStor ...

Issue with Bootstrap v3.3.6 Dropdown Functionality

previewCan someone help me figure out why my Bootstrap dropdown menu is not working correctly? I recently downloaded Bootstrap to create a custom design, and while the carousel is functioning properly, when I click on the dropdown button, the dropdown-menu ...

Retrieve the error block within an AJAX request, even if the response status is 200 OK

My cross domain request from Ajax seems to be working fine as it hits the database successfully and returns a 200 OK response. However, on the client side, it still falls into the failure block. Here's my code: validate($(".confpassword").val(),$("# ...