I have an object array and i am using gulp 4.
libs:
{
a: {
js: [
{
src: 'path/from/a1.js',
dest: 'path/to/a1.js',,
},
{
src: 'path/from/a2.js',
dest: 'path/to/a2.js',,
},
],
css: [
{
src: 'path/from/a1.css',
dest: 'path/to/b1.css',,
},
],
},
b: {
js: [
{
src: 'path/from/b.js',
dest: 'path/to/b.js',,
},
],
},
}
I need to know all the src and dest values so that I can move files from src to dest.
const moveLibs = (done) => {
Object.entries(libs).forEach(([key, value]) => {
const types = value;
Object.entries(types).forEach(([key, value]) => {
const srcAndDest = value;
Object.entries(srcAndDest).forEach(([key, value]) => {
return gulp
.src(value.src)
.pipe(gulp.dest(value.dest));
});
});
});
done();
};
This method is successful, but I feel that it is not simple enough, please tell me a simpler method, thank you.
-
\$\begingroup\$ Welcome to Code Review! As it stands the title of the post isn't describing at all what the purpose of the code is, it would be good if you could revise it, c.f. the FAQ. \$\endgroup\$ferada– ferada2021年03月17日 21:28:00 +00:00Commented Mar 17, 2021 at 21:28
2 Answers 2
A short review;
- I prefer to use the
function
keyword - You are using
libs
like a global, I would pass it in the function - If you don't need both
key
andvalue
, then you can just useObject.values
- Building on that, you might as well use a properly named function parameter and cut the lines in two
function moveLibs(libs, done){
Object.values(libs).forEach(types => {
Object.values(types).forEach(srcAndDest => {
Object.values(srcAndDest).forEach(value => {
console.log(`Piped ${value.src} to ${value.dest}`);
});
});
});
done();
};
libs=
{
a: {
js: [
{
src: 'path/from/a1.js',
dest: 'path/to/a1.js',
},
{
src: 'path/from/a2.js',
dest: 'path/to/a2.js',
},
],
css: [
{
src: 'path/from/a1.css',
dest: 'path/to/b1.css',
},
],
},
b: {
js: [
{
src: 'path/from/b.js',
dest: 'path/to/b.js',
},
],
},
};
moveLibs(libs, ()=>console.log("Hello World!"));
I would recommend a generic filter
generator. This way the code does not need any knowledge of the shape of your input and the caller is left to decide how to handle the individual values -
function* filter(t, f)
{ if (f(t)) yield t
switch(t?.constructor)
{ case Object:
case Array:
for (const v of Object.values(t))
yield *filter(v, f)
}
}
const libs =
{a:{js:[{src:'path/from/a1.js',dest:'path/to/a1.js'},{src:'path/from/a2.js',dest:'path/to/a2.js'}],css:[{src:'path/from/a1.css',dest:'path/to/b1.css'}]},b:{js:[{src:'path/from/b.js',dest:'path/to/b.js'}]}}
for (const v of filter(libs, t => t?.src && t?.dest))
console.log(JSON.stringify(v))
{"src":"path/from/a1.js","dest":"path/to/a1.js"}
{"src":"path/from/a2.js","dest":"path/to/a2.js"}
{"src":"path/from/a1.css","dest":"path/to/b1.css"}
{"src":"path/from/b.js","dest":"path/to/b.js"}
Above we wrote a lambda that checks for any t
where .src
and .dest
properties are present. Now any v
that comes out of filter
can be put through gulp
-
for (const v of filter(libs, t => t?.src && t?.dest))
gulp.src(v.src).pipe(gulp.dest(v.dest)) // <-
Note using return
in forEach
has no effect so it can be skipped entirely. ?.
is used to protect against null
or undefined
values that may appear in your tree
-
1\$\begingroup\$ Not a code review of the OP, and a counter proposal with too many Spartan variables names. \$\endgroup\$konijn– konijn2021年03月17日 19:45:36 +00:00Commented Mar 17, 2021 at 19:45
-
\$\begingroup\$ My review is that the code in question has too much knowledge of the input shape. Sorry two variables is too much for your brain to keep track of? It's a pure function, you can rename things to whatever you want \$\endgroup\$Thank you– Thank you2021年03月17日 23:51:02 +00:00Commented Mar 17, 2021 at 23:51