Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.223.172.252] |
|
Сообщ.
#1
,
|
|
|
На Node.js асинхронный вариант будет выглядеть как то так:
const fs = require('fs'); const asyncReadFile = fileName => { return new Promise((resolve, reject) => { fs.readFile(fileName, 'utf-8', (err, data) => { if (err) { return reject(new Error('Error reading file.')); } resolve(data); }); }); } const asyncWriteFile = (fileName, data) => { return new Promise((resolve, reject) => { fs.writeFile(fileName, data, err => { if (err) { return reject(new Error('Error writing file.')); } resolve('File saved.'); }); }); } Promise.all([asyncReadFile('test1.txt'), asyncReadFile('test2.txt')]) .then(data => { var data1 = data[0].trim().split('\n'); var data2 = data[1].trim().split('\n'); var results = []; var isFound; // Надо удалить циклы for for (var i = 0; i < data2.length; i++) { isFound = false; for (var j = 0; j < data1.length; j++) { if (data2[i].indexOf(data1[j]) === 0) { isFound = true; break; } } if (!isFound) { results.push(data2[i]); } } asyncWriteFile('test3.txt', results.join('\n')) .then(log => console.log(log)) .catch(err => console.log(err)); }) .catch(err => { console.log(err); }); Как удалить циклы for? Ну т.е заюзать функциональное программирование? |
Сообщ.
#2
,
|
|
|
Сам все порешал
Promise.all([asyncReadFile('test1.txt'), asyncReadFile('test2.txt')]) .then(data => { var data1 = data[0].trim().split('\n'); var data2 = data[1].trim().split('\n'); var results = []; // юзаем функции Array вместо циклов for data2.forEach(str2 => { const isEqual = str1 => str2.localeCompare(str1) === 0; if (!data1.some(isEqual)) { results.push(str2); } }); asyncWriteFile('test3.txt', results.join('\n')) .then(log => console.log(log)) .catch(err => console.log(err)); }) .catch(err => { console.log(err); }); Попутно исправил один касяк, а именно заменил indexOf на localeCompare. |
Сообщ.
#3
,
|
|
|
Продолжаю совершенствовать код
Promise.all([asyncReadFile('test1.txt'), asyncReadFile('test2.txt')]) .then(data => { const data1 = data[0].trim().split('\n'); const data2 = data[1].trim().split('\n'); const results = data2.filter(str2 => { const isEqual = str1 => str2.localeCompare(str1) === 0; return !data1.some(isEqual); }); asyncWriteFile('test3.txt', results.join('\n')) .then(log => console.log(log)) .catch(err => console.log(err)); }) .catch(err => { console.log(err); }); заменил forEach на filter. |
Сообщ.
#4
,
|
|
|
для тех кто любит Array.prototype.reduce
Promise.all([asyncReadFile('test1.txt'), asyncReadFile('test2.txt')]) .then(data => { const data1 = data[0].trim().split('\n'); const data2 = data[1].trim().split('\n'); const results = data2.reduce((accum, str2) => { const isEqual = str1 => str2.localeCompare(str1) === 0; return data1.some(isEqual) ? accum : [...accum, str2]; }, [] ); asyncWriteFile('test3.txt', results.join('\n')) .then(log => console.log(log)) .catch(err => console.log(err)); }) .catch(err => { console.log(err); }); |
Сообщ.
#5
,
|
|
|
Заключительный штрих, высший пилотаж!
Юзаем композицию const compose = (...fns) => fns.reduceRight((prevFn, nextFn) => (...args) => nextFn(prevFn(...args)), value => value ); const trimAndSplit = data => [ data[0].trim().split('\n'), data[1].trim().split('\n') ]; const getDiff = data => data[1].filter(str2 => { const isEqual = str1 => str2.localeCompare(str1) === 0; return !data[0].some(isEqual); }); const save = fileName => data => { asyncWriteFile(fileName, data.join('\n')) .then(log => console.log(log)) .catch(err => console.log(err)); }; Promise.all([asyncReadFile('test1.txt'), asyncReadFile('test2.txt')]) .then(data => { compose( save('test3.txt'), getDiff, trimAndSplit )(data); }) .catch(err => { console.log(err); }); |
Сообщ.
#6
,
|
|
|
Обнаружил касяк с выполнением асинхронногр вызова save. Заменил на асинхронный compose
// Async compose const compose = (...fns) => arg => fns.reduceRight( (accum, fn) => accum.then(fn), Promise.resolve(arg) ); Высший пилотаж! Касяк в том, что если добавить функцию в compose после save, то вызов этой функции будет выполнен перед save! Promise.all([asyncReadFile('test1.txt'), asyncReadFile('test2.txt')]) .then(data => { compose( val => console.log('to do something with `val`.'), // 4 - val is undefined save('test3.txt'), // 3 <-- async call getDiff, // 2 trimAndSplit // 1 )(data) }) .catch(err => console.log(err)); Говоря по нормальному асинхронный вызов save не синхронизирован с остальными вызовами функций. |