最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Filter nested JSON object with multiple arrays and store the filtered objects in an array - Stack Overflow

programmeradmin1浏览0评论

I want to filter the items array objects which match the "model" key in the models array and store them in an array. I did succeed in my attempt but I am not very satisfied with my effort. Are there any better ways of doing it?

Any suggestions on how to do it using underscore.js and lodash? Or using the native javascript map and filter functions?

The JSON object

 {
"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
  }
]
}

My Solution

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);
    }
   }
 }

I want to filter the items array objects which match the "model" key in the models array and store them in an array. I did succeed in my attempt but I am not very satisfied with my effort. Are there any better ways of doing it?

Any suggestions on how to do it using underscore.js and lodash? Or using the native javascript map and filter functions?

The JSON object

 {
"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
  }
]
}

My Solution

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);
    }
   }
 }
Share Improve this question edited May 31, 2017 at 22:26 1033 asked May 31, 2017 at 22:11 10331033 611 silver badge9 bronze badges 3
  • 1 in your code you access the id property but there is not track of id property in your JSON – quirimmo Commented May 31, 2017 at 22:23
  • Oops I am sorry. Just corrected – 1033 Commented May 31, 2017 at 22:28
  • @created this benchmark with me Umair and Pankaj. Pankaj wins :) – Karen Grigoryan Commented May 31, 2017 at 23:06
Add a ment  | 

4 Answers 4

Reset to default 3

I would take a slightly different approach. I guess you might like it.

 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);

You could do this:

I thought you wanted to add the year from models array too. If so, look at this implementation. This is more efficient O(n) than O(n*n) solution that you attempted earlier. For large arrays O(n*n) is not preferred.

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);

You can rewrite

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

as

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

And you can also use Array.prototype.forEach instead of a for loop, like so

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

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

I tried to keep it as similar to your solution as possible.

Try this snippet:

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)

  1. 暂无评论