Javascript 使用回退值减少对象数组
考虑以下对象:Javascript 使用回退值减少对象数组,javascript,ecmascript-6,lodash,Javascript,Ecmascript 6,Lodash,考虑以下对象: var content = [ { id: 'tab1', langCode: 'en', title: 'rocket' }, { id: 'tab1', langCode: 'da', title: 'raket' }, { id: 'tab2', langCode: 'en', title:
var content = [
{
id: 'tab1',
langCode: 'en',
title: 'rocket'
},
{
id: 'tab1',
langCode: 'da',
title: 'raket'
},
{
id: 'tab2',
langCode: 'en',
title: 'factory'
},
{
id: 'tab3',
langCode: 'es',
title: 'boligrafo'
},
];
我想将此数组缩减为一个新数组,但有以下限制:
- 没有重复的ID
- 应优先使用本地语言的值
- 如果没有本地翻译,请使用英语
- 应放弃所有其他翻译(即使它们具有唯一ID)
[
{
id: 'tab1',
langCode: 'da',
title: 'raket'
},
{
id: 'tab2',
langCode: 'en',
title: 'factory'
},
];
我的目标是使代码尽可能简短易读,我有ES6和Lodash供我完全使用。这就是我到目前为止所做的:
const LOCAL_LANG = 'da'; // Hard coded for the sake of the example
let localArr = content.filter(item => item.langCode === LOCAL_LANG);
if(LOCAL_LANG !== 'en') {
let enArr = content.filter(item => item.langCode === 'en');
for (let i = 0; i < enArr.length; i++) {
if (!_.find(localArr, { 'id': enArr[i].id})) {
localArr.push(enArr[i]);
}
}
}
const LOCAL_LANG='da';//为了示例的缘故而硬编码
让localArr=content.filter(item=>item.langCode==LOCAL\u LANG);
if(LOCAL_LANG!=“en”){
让enArr=content.filter(item=>item.langCode=='en');
for(设i=0;i
这样做很有效,但它会创建两个重复的数组,然后以我觉得很笨拙的方式将它们合并在一起。我希望看到一个更优雅的解决方案——最好是一个,在这个解决方案中,我不必多次通过阵列
另一种解决方案(可能稍微干净一点)是在第一次通过时减少langCode==='da'| | langCode==='en'
上的数组,然后删除重复项。。。但我还是觉得我错过了最明显的解决办法
谢谢 我会将所有内容简化为一个由ID键控的对象,以方便查找,而无需那些额外的
。
调用:
const targetLang = 'da';
const fallbackLang = 'en';
const itemsByKey = content.reduce((allItems, item) => {
if (item.langCode === targetLang
|| (!(item.id in allItems) && item.langCode === fallbackLang))
{
return Object.assign(allItems, { [item.id]: item });
} else {
return allItems;
}
}, {});
此解决方案只需要对原始阵列进行一次传递。如果需要将此查找对象转换回数组,则需要进行第二次传递:
var normalizedArray = Object.keys(itemsByKey).map(key => itemsByKey[key]);
您可以使用一个树来过滤想要的项目
var content=[{id:'tab1',langCode:'en',title:'rocket'},{id:'tab1',langCode:'da',title:'raket'},{id:'tab2',langCode:'en',title:'pen'},{id:'tab2',langCode:'en',title:'pen,
object=object.create(空);
content.forEach(函数(a){
对象[a.id]=对象[a.id]| |{}
对象[a.id][a.langCode]=a;
});
var result=Object.keys(Object.map(k=>Object[k][Object.keys(Object[k]).filter(l=>l!='en')[0]| |'en');
控制台日志(结果)代码>我会做如下事情
var内容=[
{
id:'表1',
语言代码:“en”,
标题:“火箭”
},
{
id:'表1',
langCode:'da',
标题:'raket'
},
{
id:'表2',
语言代码:“es”,
标题:“boligrafo”
},
{
id:'表2',
语言代码:“en”,
标题:“钢笔”
}
],
结果=内容.排序((a,b)=>a.langCode==“en”?1:-1)
.reduce((p,c)=>p.findIndex(o=>o.id==c.id)==-1?p.concat(c):p,[]);
控制台日志(结果)代码>本地语言的值应优先考虑。您如何知道?我假定英语是后备语言,但对于其他语言,我们如何知道哪一种是本地语言。@NinaScholz我将本地语言存储在一个变量中。我将把它添加到我的示例中。也许你可以添加更多的数据来反映更多的需要。