Functional Programming Way of Doing Array Conversion

Functional programming way of doing array conversion

Here is a simplified example for the same problem except the calculations:

let numbers = [3, 7, 2, 8, 3, 7, 5]
let result = numbers.isEmpty ? [] :
map(zip(numbers, numbers[1..<numbers.count])) {
(x, y) in
return (diff: x - y, mult: x * y)
}

result[0].diff // -4
result[0].mult // 21

Here I compute the differences and the multiplications of the numbers.
Note this will work only for Swift 1.2
In case you need it for earlier version, you should explore the use of Zip2.

functional programming way to flat arrays in javascript object

Use Array#reduce with Array#concat

const data = [{    addr: 111,    events: [1, 2],  },  {    addr: 222,    events: [1],  }];
const result = data.reduce((acc, {addr, events})=>{ return acc.concat(events.map(item=>({addr, events: item})));}, []);
console.log(result.sort((a,b)=>a.events-b.events));

The proper fp-ts way to convert array into object

Here's a way to achieve what you're asking.

Some notes:

  • since the dictionary is built at runtime and there is no guarantee on the keys, to prevent unsafe code the return type is Record<string, A>
  • keyGetter can't be optional, we must provide a way to came up with e key
import * as A from 'fp-ts/ReadonlyArray'
import * as R from 'fp-ts/ReadonlyRecord'
import { pipe } from 'fp-ts/function'

const arrayToRecord = <A>(
items: ReadonlyArray<A>,
keyGetter: (i: A) => string,
): Readonly<Record<string, A>> =>
pipe(
items,
A.reduce({}, (acc, item) => pipe(acc, R.upsertAt(keyGetter(item), item))),
)

EDIT

An example as requested:

const xs = [
{ id: 'abc', date: new Date() },
{ id: 'snt', date: new Date() },
]
const res = arrayToRecord(xs, (x) => x.id)

console.log(res)
// {
// abc: { id: 'abc', date: 2021-04-06T13:09:25.732Z },
// snt: { id: 'snt', date: 2021-04-06T13:09:25.732Z }
// }

EDIT 2

pipe friendly version:

declare const arrayToRecord: <A>(
keyGetter: (i: A) => string,
) => (items: ReadonlyArray<A>) => Readonly<Record<string, A>>

interface X { id: string; date: Date }

declare const xs: ReadonlyArray<X>

pipe(
xs,
arrayToRecord((x) => x.id),
) // Readonly<Record<string, X>>

Converting Javascript solution to Functional Programming Approach

You're right that Ramda's match will not help you. It's designed for simpler uses. I don't see anything substantially better than your code, although I might factor it differently:

const execAll = R.curry((re, convert, input) => {
let results = [], result;
while ((result = re.exec(input))) {
results.push(convert(result))
}
return results;
});

const parseInput = execAll(/<%([^%>]+)%>/g, match => ({
startPos: match.index,
endPos: match.index + match[0].length - 1,
matchStr: match[1]
}));

const input = "A <%test.child%><%more%> name: <%name%> age: <%age%> EOD";

parseInput(input);

Obviously, this code is structured differently, breaking apart the looping of the regex exec calls from the formatting of the output. More subtly, though, it also does not rely on the global state of the regex, using only information from the returned match results for its output. That strikes me as important for functional programming.

The call to Ramda's curry is pure gravy. You could also write this as

const execAll = (re, convert) => (input) => { /* ... */ }

This is available on the Ramda REPL, if you're interested.

Do note that this is not much changed from your approach, though. I don't see a significantly different approach applicable across a range of regular expressions.

How to convert 2 forEach loops into functional code?

You can try

aList.forEach(a -> {
if( bList.stream()
.anyMatch(b -> Objects.equals(b, a.getName()))){

abc.setId(a.getId());
abc.setValue(a.getValue());
}
});

or better

aList.stream().filter(a -> bList.stream()
.anyMatch(b -> Objects.equals(b,a.getName())))
.findAny()
.ifPresent(a -> {
abc.setId(a.getId());
abc.setValue(a.getValue());
});

javascript convert for loop filter on index to functional programming

You can do this,

var records_object =  {
"record": [
"analog",
"laser",
"monochrome",
"digital"
],
"vcd": [
12,
3,
6,
0
],
"dvd": [
1,
0,
0,
16
]
}

let arrayIndexes = records_object.record.map((item, index) => {
if(item.match(/digital/i) != null || item.match(/analog/i) !== null) {
return index;
}
}).filter(item => item !== undefined);

let newObject = Object.keys(records_object).reduce((prev, key) => {
prev[key] = records_object[key].filter((item, index) => arrayIndexes.includes(index));
return prev;
}, {});
console.log(newObject);

Converting array iteration to lambda function using Java8

A similar approach as @roookeee already posted with but maybe slightly more concise would be to store the mappings using mapping functions declared as :

Function<String, Integer> extractEmployeeId = empId -> Integer.valueOf(empId.split("-")[2]);
Function<String, BigInteger> extractDate = empId -> new BigInteger(empId.split("-")[1]);

then proceed with mapping as:

Map<Integer, BigInteger> acceptedDetailMapping = Arrays.stream(acceptedDetails)
.collect(Collectors.toMap(a -> extractEmployeeId.apply(a.getId()),
a -> extractDate.apply(a.getId())));

Map<Integer, BigInteger> rejectedDetailMapping = Arrays.stream(rejectedDetails)
.collect(Collectors.toMap(a -> extractEmployeeId.apply(a.getAd().getId()),
a -> extractDate.apply(a.getAd().getId())));

Hereafter you can also access the date of acceptance or rejection corresponding to the employeeId of the employee as well.

Elegant way to convert an array by subitems key

$source = array( 
0 => array (
'name' =>'A',
'processer' => 'XMLf'),
1 => array (
'name' =>'B',
'processer' => 'XMLp'),
2 => array (
'name' =>'C',
'processer' => 'XMLp')
);

$output = array_map(function ($value) {
return $value['name'];
}, $source);

print_r($output);

Java Functional Programming: How to convert a if-else ladder inside for loop to functional style?

The question title is quite broad (convert if-else ladder), but since the actual question asks about a specific scenario, let me offer a sample that can at least illustrate what can be done.

Because the if-else structure creates three distinct lists based on a predicate applied to the item, we can express this behavior more declaratively as a grouping operation. The only extra needed to make this work out of the box would be to collapse the multiple Boolean predicates using a tagging object. For example:

class Item {
enum Category {A, B, AB}

public Category getCategory() {
return /* ... */;
}
}

Then the logic can be expressed simply as:

Map<Item.Category, List<Item>> categorized = 
items.stream().collect(Collectors.groupingBy(Item::getCategory));

where each list can be retrieved from the map given its category.

If it's not possible to change class Item, the same effect can be achieved by moving the enum declaration and the categorization method outsize the Item class (the method would become a static method).



Related Topics



Leave a reply



Submit