如何根据条件从数组中删除重复的元素?

时间:2019-06-12 15:08:47

标签: javascript arrays ecmascript-6

如果有多个消息且元素settlementDesc不包含未涵盖或无效的数量,则尝试编写逻辑,反之亦然。我应该能够使用notCovered / invalidQuantity字符串删除重复项并保留。

数据

All these scenarios should be if messages are more then 1 in length 
Scenario#1 

    const messages = [

              {

                "settlementCode": "58",

                "settlementDesc": "Not Covered Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."

              },

              {

                "settlementCode": "58",

                "settlementDesc": "Not Covered Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."

              },

              {

                "settlementCode": "359",

                "settlementDesc": "Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."

              }

            ];

Scenario#2 

 const messages = [

              {

                "settlementCode": "58",

                "settlementDesc": "Not Covered Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."

              },

              {

                "settlementCode": "58",

                "settlementDesc": "Not Covered Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."

              }

            ];

main.js

const validateEntries = (messages) => {
  let filteredMsg;
  if (!messages) {
    return [];
  }
if(messages.length > 1) {
  console.log("Multiple messages");
  const response = [];
  let bRet = false;
  const mulitpleMessages = messages.reduce((acc,curr) => {
    if (/not covered|invalid quantity/i.test(curr.settlementDesc !== true) {
      bRet = true;
    }
    if(bRet) {
      if( acc.settlementCode == curr.settlementCode) {
        return acc;
      }
    }
    return curr;
  });
  filteredMsg = mulitpleMessages;
} else {
  filteredMsg = messages.filter((item) => {
    if (/not covered|invalid quantity/i.test(item.settlementDesc)) {
      return true;
    } else {
      return item.settlementDesc.includes(':');
    }
  });
}

  return filteredMsg;
};

console.log(validateEntries(messages));

预期的食物

Scneario#1 ouput 

    [


                  {

                    "settlementCode": "359",

                    "settlementDesc": "Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."

                  }

                ];

Scenario#2 

[

              {

                "settlementCode": "58",

                "settlementDesc": "Not Covered Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."

              }]

错误

let bRet = false;
  38 |   const mulitpleMessages = messages.reduce((acc,curr) => {
> 39 |     if (/not covered|invalid quantity/i.test(curr.settlementDesc !== true) {
     |                                                                           
  41 |       bRet = true;
  42 |     }

3 个答案:

答案 0 :(得分:1)

您可以使用嵌套的filter()

const messages = [ { "settlementCode": "58", "settlementDesc": "Not Covered Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card." }, { "settlementCode": "58", "settlementDesc": "Not Covered Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card." }, { "settlementCode": "359", "settlementDesc": "Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card." } ];

const res = messages.filter(x => 
               messages.filter(a => a.settlementCode === x.settlementCode).length === 1
            );

console.log(res)

答案 1 :(得分:0)

您仅在此行缺少右括号:

if (/not covered|invalid quantity/i.test(curr.settlementDesc !== true) {

像这样修复它:

const messages = [
    {
      "settlementCode": "58",
      "settlementDesc": "Not Covered Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."
    },
    {
      "settlementCode": "58",
      "settlementDesc": "Not Covered Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."
    },
    {
      "settlementCode": "359",
      "settlementDesc": "Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."
    }
  ];

  const validateEntries = (messages) => {
    let filteredMsg;
    if (!messages) {
      return [];
    }
  if(messages.length > 1) {
    console.log("Multiple messages");
    const response = [];
    let bRet = false;
    const mulitpleMessages = messages.reduce((acc,curr) => {
      if (/not covered|invalid quantity/i.test(curr.settlementDesc !== true)) {
        bRet = true;
      }
      if(bRet) {
        if( acc.settlementCode == curr.settlementCode) {
          return acc;
        }
      }
      return curr;
    });
    filteredMsg = mulitpleMessages;
  } else {
    filteredMsg = messages.filter((item) => {
      if (/not covered|invalid quantity/i.test(item.settlementDesc)) {
        return true;
      } else {
        return item.settlementDesc.includes(':');
      }
    });
  }

    return filteredMsg;
  };

  console.log(validateEntries(messages));

您的代码运行正常

答案 2 :(得分:0)

令我惊讶的是,这需要一些更干净,更完善的代码。我正在想像这样的解决方案:

const transform = combine (
  uniqueBy (sameProp ('settlementCode') ),
  filter (not (propMatches ('settlementDesc', ['not covered', 'invalid quantity'])))
)

所有这些辅助功能将做什么?

这个想法是combine将使用两个函数,并返回一个新函数,该函数将一个函数的输出传递给另一个函数。为此有一个标准名称compose,所以我实际上会选择这个名称。

sameProp('foo')将接受两个对象,并判断它们是否具有相等的foo属性。因此sameProp将接受一个属性名称并返回该二进制谓词。 (谓词只是返回truefalse的函数)

uniqueBy将使用一个二进制谓词和一个列表,并删除基于该谓词的所有重复项,仅保留第一个。

filter可以将Array.prototype.filter提升为独立功能。

propMatches将接受一个属性名称和一个字符串列表,返回一个接受对象的函数,并报告该对象的names属性是否与这些字符串之一匹配的正则表达式。

最后,not会简单地接受一个谓词,然后返回第二个谓词,如果第一个谓词返回false,则返回第二个谓词;如果第一个返回{{1},则返回true }}。 (也可以称为truefalseinvert。)

这是一个实现:

opposite

请注意,辅助功能,尤其是前四个功能非常简单。它们都是(可能complement除外)所有可能在应用程序的许多部分重复使用的代码。因此,它们可以存放在您的内部实用程序库中,仅保留const compose = (f, g) => (x) => f(g(x)) const filter = (fn) => (xs) => xs.filter(fn) const not = (f) => (x) => !f(x) const sameProp = (prop) => (a, b) => a [prop] === b [prop] const uniqueBy = (pred) => (xs) => xs .filter ( (x, i) => xs .findIndex (y => pred (x, y) ) == i ) const propMatches = (prop, vals, re = new RegExp (vals .join ('|'), 'i') ) => (x) => !! re .test ( x [prop] ) const transform = compose ( uniqueBy (sameProp ('settlementCode')), filter (not (propMatches ('settlementDesc', ['not covered', 'invalid quantity']))) ) const messages = [{settlementCode: "58", settlementDesc: "Not Covered Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."}, { settlementCode: "58", settlementDesc: "Not Covered Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."}, { settlementCode: "359", settlementDesc: "Needs prior authorization: System could not process your request. Call us at the toll-free number on your benefit ID card."}] console .log ( transform (messages) )(还有可能是propMatches)作为此要求的实现的一部分。

您可能还需要处理其他事情。我们可以轻松地想象一个transform的版本可以使用任意数量的函数,也可以以相反的顺序使用它们。我们还可以想象,我们可能想将一个以上的参数传递给由此产生的函数。但是我们可以在以后需要时添加这些增强功能。

或者,我们可以使用提供此类功能的实用程序库。我是Ramda的作者之一,该图书馆提供了compose(扩展版)propMatches的一个版本,称为eqProps,这是一个略有不同的{ 3}},uniqBy和称为filtercompose版本。对我来说,拥有这些始终可用的有用功能使我的许多编码工作变得更加简单。