How to transform array of arrays into an array of objects with Ramda?

ramda array to object
ramda merge arrays
ramda map object
ramda maybe
ramda transducer
ramda find in array
ramda copy object
ramda flatmap
Background

I have an array of arrays that represents a grid with the following format:

const grid = [
    [null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null],
    [null, "®" , null, null, null, null, "®" ],
    ["©" , "©" , null, null, "©" , "®" , "®" ],
    ["®" , "®" , "®" , "©" , "®" , "©" , "©" ],
    ["®" , "©" , "©" , "®" , "©" , "®" , "©" ],
];
Objective

My objective is to transform that array into the following:

const grid = [ 
    { row: 0, column: 1, value: null},
    { row: 0, column: 2, value: null},
    { row: 0, column: 3, value: null},
    //... some rows after ...
    { row: 3, column: 0, value: "©"},
    // etc...
];
Research

My first idea was to use two nested R.mapand the R.chain it. However I have a major problem: The ramda functions do not take indexes as parameters ( unlike the counter implementations in JavaScript ).

So I believe that doing this exercise using ramda, is not possible.

Question

Is there a way to do this exercise using only ramda functions ( no for loops ) ?

As discussed in comments: here is a version without ramda, but also without any for loop.

Hope you'll like it ;)

As you can see, it's totally possible to do this without any for loop, and without any overlay like ramda or another lib.

const grid = [
    [null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null],
    [null, "®" , null, null, null, null, "®" ],
    ["©" , "©" , null, null, "©" , "®" , "®" ],
    ["®" , "®" , "®" , "©" , "®" , "©" , "©" ],
    ["®" , "©" , "©" , "®" , "©" , "®" , "©" ],
];

const result = grid.reduce((r, array, i) => [...r, ...array.map((value, j) => ({row: i, column: j, value}))], []);

console.log(result);

R.lift, This would turn, for instance, Ramda's simple map function into one that more Applies a function to the value at the given index of an array, returning a new Objects will be merged directly or 2-item arrays will be merged as key, value pairs. Part of the problem is that Ramda has really not tried before to introduce types to our users. We simply operate on a few built-in types such as Lists (via arrays), Objects, Strings, and Numbers. For anything else, we simply dispatch to user implementations. So introducing not only a new type but a complicated one at that is a scary prospect.

Solution

Using the solution from @sjahan The natural solution using Ramda is as follow:

const R  require("ramda");
const mapIndexed = R.addIndex( R.map );
const reduceIndexed = R.addIndex( R.reduce );

const convertGrid = reduceIndexed(
  ( acc, array, i ) => [...acc, ...mapIndexed( ( value, j ) => ( { row: i, column: j, value } ), array ) ],
  [ ]
);

Compose, This would turn, for instance, R.map function into one that more closely Applies a function to the value at the given index of an array, returning a new copy of Creates a deep copy of the value which may contain (nested) Array s and Object s. An array-like object whose value at the supplied index will be replaced. Returns Array A copy of the supplied array-like object with the element at index `idx` replaced with the value returned by applying `fn` to the existing element. Added in v0.14.0. Applies a function to the value at the given index of an array, returning a new copy of

A different approach using Ramda is to map over the rows to add their column index, then transpose the grid, then map over it again to add row index to each column.

const grid = [
    [null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null],
    [null, "®" , null, null, null, null, "®" ],
    ["©" , "©" , null, null, "©" , "®" , "®" ],
    ["®" , "®" , "®" , "©" , "®" , "©" , "©" ],
    ["®" , "©" , "©" , "®" , "©" , "®" , "©" ],
];

const mapCol = R.addIndex(R.map)(R.flip(R.assoc('column')))
const mapRow = R.addIndex(R.map)(R.flip(R.assoc('row')))
const mapVal = R.map(R.objOf('value'))

const fn = R.pipe(
  R.map(mapVal),  // convert each value to `{ value: ... }`
  R.map(mapCol),  // add the column index `{ value: ..., column: n }`
  R.transpose,    // transpose the whole grid
  R.chain(mapRow) // add the row index `{ value: ..., column: n, row: m }`
)

console.log(fn(grid))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

compose Function, Note: commute may be more useful to convert a list of non-Array Functors (e.g. object by evolving a shallow copy of object , according to the transformation functions. Flatten all arrays in the list but leave other values alone. var flattenArrays  Convert Array of Arrays into Object with key-value pair in Javascript (Data from websocket) So in one of my project, I faced a challenge in JavaScript which i would like to share with you guys. The Challenge. From a websocket, I was getting the data in the multidimensional array i.e I was getting Array of arrays.

A simple nested loop does it:

 const result = [];

 for(const [row, content] of grid.entries()) {
    for(const [column, value] of content.entries()) {
       result.push({ row, column, value });
    }
}

R.evolve turns arrays into objects · Issue #1207 · ramda/ramda , Note that evolve already recurses into arrays, in the sense that apart the object Since the returned object still behaves like an array to some extent, the way you want to transform args (you can change order, or sum them,  convert: Convert object to array; rangeStep: Create an incrementing or decrementing range of numbers with a step; filterWithKeys: Filter an object using keys as well as values; diffObjs: diffing objects (similar to Guava's Maps.Difference) Convert a list of property-lists (with header) into a list of objects; mapPath: Map over the value at the

Functional Programming in JS with Ramda: Arrays and Objects, If you don't know already arrays and objects in JS are mutable. That means that Array example import update from 'ramda/src/update'const array = [1,2,3,4,5] { name: toUpper }, // The transformation object // This consists of  Java 8 provides another simple approach to convert object array to integer array. Below are the steps: Convert the specified object array to a sequential Stream. Use Stream.map() to convert every object in the stream to their integer representation. Use toArray() method to accumulate elements of the stream into a new integer array.

Iterating Over and Reducing Data, That copy is now a separate data object that you can edit without effecting the original useful tool to implement this concept of a transformation on immutable data. The callback function gets called for each element in the array, and also has (as far as I can tell) they only accept arrays of raw numbers instead of objects. In this lesson we're going to talk about that how to convert a list of integers to an array in python programming language.

Thinking in Ramda: Immutability and Arrays, In Part 6, we talked about working with JavaScript objects in a Ramda has even more methods for reading array elements. We've learned ways of reading​, updating, and transforming object properties and array elements. Learn to convert ArrayList to array using toArray () method with example. toArray () method returns an array containing all of the elements in the list in proper sequence (from first to last element). toArray () is overloaded method and comes in two forms: The first method does not accept any argument and returns the array of object type.

Comments
  • Did you consider using vanilla JS? I don't know ramda, but I'm pretty sure you can get a clean functionnal version with vanilla JS to get your expected output.
  • If the problem is the missing indexes, I think ramdajs.com/0.21.0/docs/#addIndex will be able to help by decorating with the indexes you need? Most functional languages have similar capabilities, like zipWithIndex in Scala.
  • I'm not familiar with ramda but it has also mapObjIndexed.
  • I am very well aware of the possibility of doing it without ramda. That was not the question. The challenge is in using it :P
  • Allow me to re-iterate the questions being asked: Is there a way to do this exercise using only ramda functions ( no for loops ) ?