2017-05-31 114 views
0

我想过滤与models数组中的“model”键匹配的items数组对象,并将它们存储在数组中。我的努力取得了成功,但我对我的努力并不满意。有没有更好的方法来做到这一点?使用多个数组过滤嵌套的JSON对象并将过滤的对象存储在数组中

有关如何使用underscore.js和lodash执行操作的任何建议?或者使用本地JavaScript映射和过滤器功能?

JSON对象

{ 
"items": [ 
    { 
    "model": "ooc0d", 
    "code": "2x4qr", 
    "price": 33 
    }, 
    { 
    "model": "ruie9", 
    "code": "2f6gi", 
    "price": 22 
    }, 
    { 
    "model": "aqu0d", 
    "code": "2f6gi", 
    "price": 21 
    }, 
    { 
    "model": "ddebd", 
    "code": "2f6gi", 
    "price": 25 
    }, 
    { 
    "model": "ddebd", 
    "code": "2f6gi", 
    "price": 29 
    } 
], 
"models": [ 
    { 
    "model": "ruie9", 
    "year": 1998 
    }, 
    { 
    "model": "ooc0d", 
    "year": 1991 
    }, 
    { 
    "model": "aqu0d", 
    "year": 1994 
    }, 
    { 
    "model": "ddebd", 
    "year": 1995 
    }, 
    { 
    "model": "odq76", 
    "year": 1999 
    } 
] 
} 

我的解决方案

const { models, items } = jsonData; 

const newarray = []; 

for(let i = 0; i < models.length; i++) { 
    for(let j = 0; j < items.length; j++) { 
    if(items[j].model===models[i].model) { 

     let obj = { 
     ...items[j], 
     year: models[i].year 
     } 
     newarray.push(obj); 
    } 
    } 
} 
+1

您访问'id'财产,但有你的JSON – quirimmo

+0

不跟踪id属性哎呀对不起。刚刚纠正 – 1033

+0

@创建了这个[基准](https://jsfiddle.net/sf5jtru6/)与我Umair和Pankaj。 Pankaj获胜:) –

回答

1

可以重写

let obj = { 
    ...items[j], 
    year: models[i].year 
} 

let obj = Object.assign({}, items[j], { year: models[i].year }); 

而且你还可以使用Array.prototype.forEach代替for循环,像这样

models.forEach((m) => { 
    items.forEach((i) => { 
    if (m.id === i.id) { 
     let obj = Object.assign({}, i, { year: m.year }); 

     newArray.push(obj); 
    } 
    }) 
}) 

我试图保持它类似于您的解决方案成为可能。

+0

谢谢你!它看起来更干净:D – 1033

1

试试这个片断:

const jsonData = { 
 
    "items": [{ 
 
     "model": "ooc0d", 
 
     "code": "2x4qr", 
 
     "price": 33 
 
    }, 
 
    { 
 
     "model": "ruie9", 
 
     "code": "2f6gi", 
 
     "price": 22 
 
    }, 
 
    { 
 
     "model": "aqu0d", 
 
     "code": "2f6gi", 
 
     "price": 21 
 
    }, 
 
    { 
 
     "model": "ddebd", 
 
     "code": "2f6gi", 
 
     "price": 25 
 
    }, 
 
    { 
 
     "model": "ddebd", 
 
     "code": "2f6gi", 
 
     "price": 29 
 
    } 
 
    ], 
 
    "models": [{ 
 
     "model": "ruie9", 
 
     "year": 1998 
 
    }, 
 
    { 
 
     "model": "ooc0d", 
 
     "year": 1991 
 
    }, 
 
    { 
 
     "model": "aqu0d", 
 
     "year": 1994 
 
    }, 
 
    { 
 
     "model": "ddebd", 
 
     "year": 1995 
 
    }, 
 
    { 
 
     "model": "odq76", 
 
     "year": 1999 
 
    } 
 
    ] 
 
}; 
 

 
var newArray = jsonData.models.reduce(
 
    (acc, modelData) => { 
 
    let filteredItems = jsonData.items.filter(item => item.model === modelData.model); 
 
    if (filteredItems.length) { 
 
     acc.push(...filteredItems); 
 
    } 
 
    return acc; 
 
    }, []) 
 

 
console.log(newArray);

+0

谢谢man :)我可以知道'[]'在reduce函数的末尾做了什么吗? – 1033

+0

嗯,这是一个更干净的解决方案,但是您在每次迭代时都运行“过滤器”,这是IMO详尽无遗的。 – Umair

+1

@ 1033永远欢迎。 '[]'是'acc'的初始值,如果省略则是可选的,那么'acc'的第一个值将是'jsonData.models'的第一个元素。 –

2

我将采取略有不同的方法。我想你可能会喜欢它。

const models = [ 
 
     { 
 
     "model": "ruie9", 
 
     "year": 1998 
 
     }, 
 
     { 
 
     "model": "not-found", 
 
     "year": 1991 
 
     }, 
 
     { 
 
     "model": "aqu0d", 
 
     "year": 1994 
 
     }, 
 
     { 
 
     "model": "ddebd", 
 
     "year": 1995 
 
     }, 
 
     { 
 
     "model": "odq76", 
 
     "year": 1999 
 
     } 
 
    ]; 
 
    
 
    const items = [ 
 
     { 
 
     "model": "ooc0d", 
 
     "code": "2x4qr", 
 
     "price": 33 
 
     }, 
 
     { 
 
     "model": "ruie9", 
 
     "code": "2f6gi", 
 
     "price": 22 
 
     }, 
 
     { 
 
     "model": "aqu0d", 
 
     "code": "2f6gi", 
 
     "price": 21 
 
     }, 
 
     { 
 
     "model": "ddebd", 
 
     "code": "2f6gi", 
 
     "price": 25 
 
     }, 
 
     { 
 
     "model": "ddebd", 
 
     "code": "2f6gi", 
 
     "price": 29 
 
     } 
 
    ]; 
 
    
 
    
 
    
 
    const transformed = models.reduce((res, val) => { 
 
     res[val.model] = val; 
 
     
 
     return res; 
 
    }, {}); // Transform models into a dictionary. 
 
    
 
    
 
    const filtered = items.filter(i => i.model in transformed); 
 
    
 
    console.log(filtered);

+0

谢谢男人:)这是我见过的最好的一个。 – 1033

+0

@ 1033很高兴我能帮到你。 – Umair

+1

此外,通过使用这种方法,您只需循环一次“模型”列表,而不必在每次迭代中循环遍历它。 – Umair

2

你可以这样做:

我想你想从models阵列添加今年也。 如果是这样,看看这个实现。这比您之前尝试的解决方案更有效率O(n)O(n*n)更有效。对于大型阵列O(n*n)不是优选的。

let items = [{ 
 
    "model": "ooc0d", 
 
    "code": "2x4qr", 
 
    "price": 33 
 
    }, 
 
    { 
 
    "model": "ruie9", 
 
    "code": "2f6gi", 
 
    "price": 22 
 
    }, 
 
    { 
 
    "model": "aqu0d", 
 
    "code": "2f6gi", 
 
    "price": 21 
 
    }, 
 
    { 
 
    "model": "ddebd", 
 
    "code": "2f6gi", 
 
    "price": 25 
 
    }, 
 
    { 
 
    "model": "ddebd", 
 
    "code": "2f6gi", 
 
    "price": 29 
 
    } 
 
]; 
 

 
let models = [ 
 
    { 
 
    "model": "ruie9", 
 
    "year": 1998 
 
    }, 
 
    { 
 
    "model": "ooc0d", 
 
    "year": 1991 
 
    }, 
 
    { 
 
    "model": "aqu0d", 
 
    "year": 1994 
 
    } 
 
]; 
 

 
let objModels = models.reduce(function(r,v) { 
 
r[v.model] = v; 
 
return r; 
 
}, {}); 
 

 
let objItems = items.reduce(function(r,v) { 
 
r[v.model] = v; 
 
return r; 
 
}, {}); 
 

 
let ans = []; 
 
for(let key in objItems) { 
 
    if(key in objModels) { 
 
    let o = objItems[key]; 
 
    o.year = objModels[key].year; 
 
    ans.push(o); 
 
    
 
    } 
 
} 
 

 
console.log(ans);

在你的代码
+0

你[赢](https://jsfiddle.net/sf5jtru6/)恭喜。 –

+0

太棒了!你能解释我的解决方案的复杂性是“O(n * n)”吗? – Umair

+0

@Umair我什么时候说你是'O(n * n)'?这是给OP的。但是,你的解决方案甚至不是OP所需要的。他也想要“年”。看看OP的'year:models [i] .year'的尝试解决方案。 –