Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/478.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript如何从映射返回数组_Javascript_Arrays_Ramda.js - Fatal编程技术网

Javascript如何从映射返回数组

Javascript如何从映射返回数组,javascript,arrays,ramda.js,Javascript,Arrays,Ramda.js,我有下面的Json var myjson = [{ "files": [ { "domain": "d", "units": [ { "key": "key1", "type": "2"

我有下面的Json

   var myjson =   [{

            "files": [
                {
                    "domain": "d",
                    "units": [
                        {
                            "key": "key1",
                            "type": "2"

                  },
                        {
                            "key": "key2",
                            "type": "2"
                  },
                        {
                            "key": "key3",
                            "type": "2"
                  }]

            },

                {
                    "domain": "d1",
                    "units": [
                        {
                            "key": "key11",
                            "type": "2"

                  },
                        {
                            "key": "key12",
                            "type": "2"
                  },
                        {
                            "key": "key13",
                            "type": "2"
                  }]

            }]

            },

        {

            "files": [
                {
                    "domain": "d",
                    "units": [
                        {
    ......
我想从这个Json数组创建一个新数组。数组的长度将是这个Json对象中的“单位”数

所以我需要提取“单位”,并从父对象添加一些数据

units: [{
        domain: "",
        type: "",
        key: ""
    }, {
        domain: "",
        type: "",
        key: ""
    },
    {
        domain: "",
        type: "",
        key: ""
    }
....
    ];
我想我大概可以这样做:

var res = [];

myjson.forEach(function(row) {
     row.files.forEach(function(tfile) {
         tfile.units.forEach(function(unit) {

            var testEntity = {
                domain: tfile.domain,
                type : unit.type,
                key: unit.key

            };

            res.push(testEntity);

        });
    });
});
但是它很难阅读,看起来也不太好。我想做一些类似的事情:

var RESULT = myjson.map(function(row) {
     return row.files.map(function(tfile) {
        return  tfile.units.map(function(unit) {

            return {
                domain: tfile.domain,
                type : unit.type,
                key: unit.key

            };



        });
    });
});
但这不起作用,看起来也不好。是否有任何方法可以做到这一点,也许是以更具声明性的方式。希望Ramda.js能帮上忙

一般来说,有什么好方法可以以可读的方式从任何嵌套的json中获取数据吗

实施类似于:

nestedjson.findAllOnLastlevel(function(item){

return {
key : item.key,
type: type.key,
domain : item.parent.domain}

});
或者以某种方式展平此json,以便将来自所有父对象的所有属性移动到leafs子对象。myjson.flatte(“files.units”)

杰斯宾


非常感谢

像这样的事情应该行得通
.reduce
适用于此类情况

const allUnits = myjson.reduce((acc, anonObj) => {
   const units = anonObj.files.map(fileObj => {
     return fileObj.units.map(unit => {
       return {...unit, domain: fileObj.domain})
   })
   return [...acc, ...units]
}, [])
请注意,这依赖于阵列扩展和对象扩展,这是ES6的功能,并非每个平台都支持

如果您不能使用ES6,这里有一个ES5实现。没有那么漂亮,但做了同样的事情:

var allUnits = myjson.reduce(function (acc, anonObj) {
   const units = anonObj.files.map(function(fileObj) {
     // for each fileObject, return an array of processed unit objects
     // with domain property added from fileObj
     return fileObj.units.map(function(unit) {
       return {
         key: unit.key,
         type: unit.type,
         domain: fileObj.domain
       }
     })
   })
   // for each file array, add unit objects from that array to accumulator array
   return acc.concat(units)
}, [])
试试这个

var myjson=[{
“文件”:[{
“域”:“d”,
“单位”:[{
“键”:“键1”,
“类型”:“2”
}, {
“键”:“键2”,
“类型”:“2”
}, {
“键”:“键3”,
“类型”:“2”
}]
},
{
“域”:“d1”,
“单位”:[{
“键”:“键11”,
“类型”:“2”
}, {
“键”:“键12”,
“类型”:“2”
}, {
“键”:“键13”,
“类型”:“2”
}]
}
]
}];
//首先筛选出排除单元的属性
var结果=[];
forEach(函数(obj){
forEach(函数(obj2){
结果=结果.concat(obj2.units.map)(函数(单位){
unit.domain=obj2.domain;
返回单元;
}));
});
});

控制台日志(结果)
这里可以使用的函数是Ramda的函数,而不是
R.map
。您可以将
R.chain
视为一种映射列表的方法,该方法使用一个函数返回另一个列表,然后将结果列表平铺在一起

// get a list of all files
const listOfFiles =
  R.chain(R.prop('files'), myjson)

// a function that we can use to add the domain to each unit
const unitsWithDomain =
  (domain, units) => R.map(R.assoc('domain', domain), units)

// take the list of files and add the domain to each of its units
const result =
  R.chain(file => unitsWithDomain(file.domain, file.units), listOfFiles)
如果您想更进一步,还可以使用which来帮助组合函数,这些函数在每个给定函数之间的行为类似于
R.chain

// this creates a function that accepts the `myjson` list
// then passes the list of files to the second function
// returning the list of units for each file with the domain attached
const process = pipeK(prop('files'),
                      f => map(assoc('domain', f.domain), f.units))

// giving the `myjson` object produces the same result as above
process(myjson)

纯JS足以在简单的一行程序中产生结果。我不会为了这份工作去碰任何图书馆。我这里有两种方法。第一个是reduce.reduce.map链,第二个是reduce.map.map链。这是代码

var myjson=[{“文件”:[{“域”:“d”,“单位”:[{“键”:“键1”,“类型”:“2”},{“键2”,“类型”:“键3”,“类型”:“2”},{“域”:“d1”,“单位”:[{“键”:“键11”,“类型”:“2”},{“键12”,“类型”:“2”},{“键”:“键13”,“类型”:“2”},{“键2”},},{“文件”:“域”:“e单位”:“键1”,“类型”:“键1”,“键2”{“键2”},{“键2”},{“键2”},{“2”},{“域”:“e1”,“单元”:[{“键”:“键11”,“类型”:“2”},{“键”:“键12”,“类型”:“2”},{“键”:“键13”,“类型”:“2”}]}],
units=myjson.reduce((p,c)=>c.files.reduce((f,s)=>f.concat(s.units.map(e=>(e.domain=s.domain,e))),p),[]);
units2=myjson.reduce((p,c)=>p.concat(…c.files.map(f=>f.units.map(e=>(e.domain=f.domain,e))),[];
控制台日志(单位);

console.log(units2);
所以你需要一个工作版本,你已经有了,或者一个好看的版本,可以用ES6风格完成?现在我有了一个工作版本,但我做了很多这种“嵌套json操作”“正在考虑一种适当的方法。甚至可能是一些一般的方法。我提供的json被简化了。可能更深。另外,新的“=>”在我的例子中不可用。主要问题是要知道迭代哪个属性。您可以使用递归方法给出路径,但至少需要重新组合属性。works可以提供不需要var result=[]的内容;可以吗?以不变的方式?映射总是返回一个结果吗?它是否可以返回“类多”
键是missed@Ant所有三个级别的映射都将返回类似于
[[[{key:'key1',value:'1'}]]]
的内容,要克服这一问题,您需要编写代码来接受单个项,然后将其连接到数组中。因为你想要一个更短的代码,所以我不能让它比这个更短:)我有ES5,没有办法改变它:(看起来不错-我简化了我的json,如果我有多(五)个属性需要在同一个地方关联,比如domain?和第一级prop1上的几个其他属性:“值”,文件:{…我在这里添加了
var result=R.pipe(R.chain(函数(p){返回R.map(R.assoc('parent',p,p.files)})、R.chain(函数(p){返回R.map(R.assoc('parent',p,p.units)})、R.chain(函数(k){返回{域:k.parent.domain,prop1:k.parent.parent.prop1,键:k.key}}))(myjson)
是的,这需要在每个步骤中将属性值作为状态线程化。