简体   繁体   中英

JavaScript: Filter Array of Shoe Objects for Specific Type of Shoes and Return Object Array with Index as Property

I have the following array of shoe objects:

var currentInventory = [
  {
    name: 'Brunello Cucinelli',
    shoes: [
      {name: 'tasselled black low-top lace-up', price: 1000},
      {name: 'tasselled green low-top lace-up', price: 1100},
      {name: 'plain beige suede moccasin', price: 950},
      {name: 'plain olive suede moccasin', price: 1050}
    ]
  },
  {
    name: 'Gucci',
    shoes: [
      {name: 'red leather laced sneakers', price: 800},
      {name: 'black leather laced sneakers', price: 900}
    ]
  }
];

Using the currentInventory array above, I want to find all the laced shoes and indicate which word contains lace:

Desired output below:

[
  {
    "nameWords": [
      "tasselled",
      "black",
      "low-top",
      "lace-up"
    ],
    "targetWordIndex": 3
  },
  {
    "nameWords": [
      "tasselled",
      "green",
      "low-top",
      "lace-up"
    ],
    "targetWordIndex": 3
  },
  {
    "nameWords": [
      "red",
      "leather",
      "laced",
      "sneakers"
    ],
    "targetWordIndex": 2
  },
  {
    "nameWords": [
      "black",
      "leather",
      "laced",
      "sneakers"
    ],
    "targetWordIndex": 2
  }
]

Below is my attempted code; it comes close but not quite there:

function renderLacedShoes(inventory) {

  //console.log(inventory)

  let finalArr = []; 


  for (let i=0; i<inventory.length; i++){
    let indObj = inventory[i];

    let newObj = {};

    // dive into values associated with shoes 

    for (let k=0; k<indObj.shoes.length; k++){
      let shoeNameArr = indObj.shoes[k].name.split(" ");    

      //console.log(shoeNameArr)

      if ( (shoeNameArr.includes('lace-up')) || (shoeNameArr.includes('laced')) ){

        newObj['nameWords'] = shoeNameArr;
        console.log(newObj)

        // not working below
        newObj['targetWordIndex'] = (shoeNameArr.indexOf('lace-up' || 'laced'))
      }
    }
    finalArr.push(newObj);
  }
  return finalArr;
}


// TEST: 
renderLacedShoes(currentInventory)

My code outputs:

[ { nameWords: [ 'tasselled', 'green', 'low-top', 'lace-up' ],
    targetWordIndex: 3 },
  { nameWords: [ 'black', 'leather', 'laced', 'sneakers' ],
    targetWordIndex: -1 } ]

I see two issues: It's not returning ALL the "lace" containing shoes. Also, my targetWordIndex is off.

What am I doing wrong?

You have not only a problem with the index, but also with the pushing the result. This should take place inside of the inner loop.

 function renderLacedShoes(inventory) { let finalArr = []; for (let i = 0; i < inventory.length; i++) { let indObj = inventory[i]; for (let k = 0; k < indObj.shoes.length; k++) { let nameWords = indObj.shoes[k].name.split(" "); let targetWordIndex = nameWords.findIndex(s => s === 'lace-up' || s === 'laced'); if (targetWordIndex !== -1) { finalArr.push({ nameWords, targetWordIndex }); } } } return finalArr; } var currentInventory = [{ name: 'Brunello Cucinelli', shoes: [{ name: 'tasselled black low-top lace-up', price: 1000 }, { name: 'tasselled green low-top lace-up', price: 1100 }, { name: 'plain beige suede moccasin', price: 950 }, { name: 'plain olive suede moccasin', price: 1050 }] }, { name: 'Gucci', shoes: [{ name: 'red leather laced sneakers', price: 800 }, { name: 'black leather laced sneakers', price: 900 }] }], result = renderLacedShoes(currentInventory); console.log(result);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

 let renderLacedShoes = (arr) => {
    const array = [];
    arr.forEach(elem => {
        elem.shoes.forEach(names => {
            let nameWords = names.name.split(" ");
            nameWords.forEach((elem, i) => {
                if (elem.indexOf("lace") >= 0) {
                    array.push({
                        nameWords: nameWords,
                        targetWordIndex: i
                    });
                }
            });

        });
    });
    return array;
}

You can attempt it using a chain of map and filter to reach to desired solution

 var res = [{ name: 'Brunello Cucinelli', shoes: [{ name: 'tasselled black low-top lace-up', price: 1000 }, { name: 'tasselled green low-top lace-up', price: 1100 }, { name: 'plain beige suede moccasin', price: 950 }, { name: 'plain olive suede moccasin', price: 1050 }] }, { name: 'Gucci', shoes: [{ name: 'red leather laced sneakers', price: 800 }, { name: 'black leather laced sneakers', price: 900 }] }] .map(d => d.shoes.map(r => r.name)).flat() .filter(d => d.includes('lace')) .map(d => ({ nameWords: d.split(' '), targetWordIndex: d.split(' ').findIndex(d => d.includes('lace'))})) console.log(res)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM