2017-01-24 45 views
1

我有一個對象數組,我試圖通過抓取第一個子對象來匹配我給它的某個對象。所以,我的目標看起來像這樣:Javascript,返回匹配的第一個(子)對象

const filteredVariants = [ 
{ 
    name: "Test0", 
    images: [ 
    { 
    name: "test0img1", 
    shot_type: "swatch" 
    }] 
    }, { 
    name: "Test1", 
    images: [ 
    { 
    name: "test1img1", 
    shot_type: "product" 
    }, 
    { 
    name: "test1img2", 
    shot_type: "product" 
    }] 
}] 

所以我所希望做的是通過這個對象看,特別是內images,發現有shot_type: "product"的第一個對象,並返回。所以,在這種情況下,我試圖讓它回到我:

{ 
name: "test1img1", 
shot_type: "product" 
} 

這是我到目前爲止有:

const firstProductImage = _.find(filteredVariants, _.flow(
    _.property('images'), 
    _.partialRight(_.some, { shot_type: 'product' }) 
)); 

這部分是存在的方式,除了它返回的整個父對象,當我只需要孩子的圖像對象。我試着跑過地圖和過濾器,但這些方法並不像這個那樣乾淨。我想知道是否有辦法告訴lodash在這種情況下只返回匹配{ shot_type: 'product' }的第一個子節點。

我使用lodash,但如果這是可能的普通的JavaScript,這將是很好的。謝謝!

回答

1

您可以迭代filteredVariantsimages,如果找到,則將該對象指定爲result。返回的真值將結束兩個循環。

版本與Array#some

var filteredVariants = [{ name: "Test0", images: [{ name: "test0img1", shot_type: "swatch" }]}, { name: "Test1", images: [{ name: "test1img1", shot_type: "product" }, { name: "test1img2", shot_type: "product" }] }], 
 
    result; 
 

 
filteredVariants.some(variant => 
 
    variant.images.some(image => image.shot_type === "product" && (result = image)) 
 
); 
 

 
console.log(result);

版本與Array#reduceArray#find

var variants = [{ name: "Test0", images: [{ name: "test0img1", shot_type: "swatch" }]}, { name: "Test1", images: [{ name: "test1img1", shot_type: "product" }, { name: "test1img2", shot_type: "product" }] }], 
 
    result = variants.reduce((r, variant) => 
 
     r || variant.images.find(image => image.shot_type === "product"), 
 
     undefined 
 
    ); 
 

 
console.log(result);

1

如何如下:

const filteredVariants = [ 
 
{ 
 
    name: "Test0", 
 
    images: [ 
 
    { 
 
    name: "test0img1", 
 
    shot_type: "swatch" 
 
    }] 
 
    }, { 
 
    name: "Test1", 
 
    images: [ 
 
    { 
 
    name: "test1img1", 
 
    shot_type: "product" 
 
    }, 
 
    { 
 
    name: "test1img2", 
 
    shot_type: "product" 
 
    }] 
 
}] 
 

 
var searchObject = { shot_type: 'product' }; 
 

 

 
// V------------ implementation here 
 
var foundObject = _.reduce(
 
    filteredVariants, 
 
    (last, next) => last || _.find(next.images, searchObject), 
 
    null 
 
); 
 

 

 
console.log(foundObject);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

1

這是絕對有可能的,而且很可能減少混亂純JS:

const filteredVariants = 
 
[ 
 
    { 
 
    name: "Test0", 
 
    images: [{name: "test0img1", shot_type: "swatch"}] 
 
    }, 
 
    { 
 
    name: "Test1", 
 
    images: [ 
 
     {name: "test1img1", shot_type: "product"}, 
 
     {name: "test1img2", shot_type: "product"} 
 
    ] 
 
    } 
 
] 
 
// compare an object to a given model. 
 
function compare(object, model){ 
 
    for(str in model) 
 
     if(object[str] != model[str]) 
 
     return false; 
 
    return true; 
 
} 
 
// gets all 'images" properties, iterates over them and returns the first 
 
// one that matches. returns null if nothing works 
 
function findImage(array, model){ 
 
    for(var i in filteredVariants){ 
 
    var obj = filteredVariants[i], 
 
    images = obj.images; 
 
    for(var j in images){ 
 
     if(compare(images[j], model)) 
 
     return images[j]; 
 
    } 
 
    } 
 
    return null; 
 
} 
 

 
console.log(findImage(filteredVariants, {shot_type: "product"}));