如何删除外部阵列?

时间:2019-03-26 01:48:12

标签: javascript arrays ramda.js

我正在遍历嵌套对象。返回数据由两个数组包装。我理解为什么会这样,但是我不明白如何获取所需的数据。

const data = {
  "foo": {
    "bar": {
      "id": "1",
      "step": [{
        "id": "33",
        "copy": [{
            "id": "1",
            "text": "hello",
          },
          {
            "id": "2",
            "text": "whirl",
          },
          {
            "id": "3",
            "text": "whoa",
          }
        ],
      }]
    }

  }
}

pipe(
  path(['foo', 'bar', 'step']),
  map(step => 
    step.copy.map(s => ({text: s.text}))
  )
) (data)

返回数据返回此:

[[{"text": "hello"}, {"text": "whirl"}, {"text": "whoa"}]]

我想把这个退回去

[{"text": "hello"}, {"text": "whirl"}, {"text": "whoa"}]

5 个答案:

答案 0 :(得分:2)

问题在于step本身就是array。您需要获取其第一项或在参数中传递0。这是从路径查找数据的纯js版本。我使用了reduce()

const data = { "foo": { "bar": { "id": "1", "step": [{ "id": "33", "copy": [{ "id": "1", "text": "hello" }, { "id": "2", "text": "whirl" }, { "id": "3", "text": "whoa" } ] }] } } }

function getFromPath(obj, path) {
  return path.reduce((ac, a) => ac[a] || {}, obj);
}
let res = getFromPath(data, ["foo","bar","step",0,"copy"]).map(({text}) => ({text}))
console.log(res)

答案 1 :(得分:1)

使用 Ramda.js 来实现所需功能的一种解决方案是在app.use('/', function (req, res, next) { // Check 1 console.log('Request URL:', req.originalUrl) next() }, function (req, res, next) { // Check 2: Pass first check console.log('Request Type:', req.method) next() }) app.get('/', (req, res) => { // Final Route }); 之后插入https://expressjs.com/en/guide/using-middleware.html

app.use('/first', function (req, res, next) {
    passport.use(
        new GoogleStrategy({
            callbackURL: '/google/redirect',
            clientID: keys.google.clientID,
            clientSecret: keys.google.clientSecret
        }, function (accessToken, refreshToken, profile, done){
            if (profile._json.hd === "HIDDEN-DOMAIN.COM") {
                User.findOne({googleId : profile.id})
                    .then(function(currentUser){
                        if(currentUser){
                            console.log('User with ID' + currentUser.googleId +' already exists. No new entry was made');
                            done(null, currentUser);
                        } else {
                            new User({
                                username: profile.displayName,
                                googleId: profile.id
                            })
                                .save()
                                .then(function(newUser){
                                    console.log('New user created: ' + newUser);
                                    done(null, newUser);
                                    next(); // next();
                                });
                        }
                    })
            } else {
                console.log(__dirname);
                next(); // next();
            }
        }));

}, function (req, res, next) {
    // More checks
    next()
});

app('/', (req, res) => {
    // final route here
    res.sendFile('../login.html');
})
R.map()
const data = {
  "foo": {
    "bar": {
      "id": "1",
      "step": [{
        "id": "33",
        "copy": [
          {"id": "1", "text": "hello"},
          {"id": "2", "text": "whirl"},
          {"id": "3", "text": "whoa"}
        ],
      }]
    }
  }
}

let res = R.pipe(
  R.path(['foo', 'bar', 'step']),
  R.map(step => step.copy.map(s => ({text: s.text}))),
  R.flatten
) (data)

console.log(res);

另一种解决方案可能是将外部.as-console {background-color:black !important; color:lime;} .as-console-wrapper {max-height:100% !important; top:0;}替换为R.flatten

<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
R.map()
const data = {
  "foo": {
    "bar": {
      "id": "1",
      "step": [{
        "id": "33",
        "copy": [
          {"id": "1", "text": "hello"},
          {"id": "2", "text": "whirl"},
          {"id": "3", "text": "whoa"}
        ],
      }]
    }
  }
}

let res = R.pipe(
  R.path(['foo', 'bar', 'step']),
  R.reduce((acc, curr) => acc.concat(curr.copy.map(({text}) => ({text}))), [])
) (data)

console.log(res);

答案 2 :(得分:1)

我对您的代码最简单的解决方法是将外部map替换为chain。您可以选择使用flatten,或者最好使用unnest,但可以将chain认为(至少在应用于数组时;实际上更通用)为map然后是unnest

那会做你想要的。但是我建议,如果您要对其余部分使用无点Ramda代码,则还应替换内部的lambda以达到以下目的:

const transform = pipe(
  path(['foo', 'bar', 'step']),
  chain(prop('copy')),
  project(['text'])
)

const data = {"foo": {"bar": {"id": "1", "step": [{"copy": [{"id": "1", "text": "hello"}, {"id": "2", "text": "whirl"}, {"id": "3", "text": "whoa"}], "id": "33"}]}}}

console.log(transform(data))
<script src="//bundle.run/ramda@0.26.1"></script>
<script>
const {pipe, path, chain, prop, project} = ramda
</script>

这对我来说看起来不错。但是请注意,解压缩使原始JS处理起来比以前更加整洁。这也应该起作用:

const transform = ({foo: {bar: {step}}}) => step.flatMap(
  ({copy}) => copy.map(({text}) => ({text}))
)

const data = {"foo": {"bar": {"id": "1", "step": [{"copy": [{"id": "1", "text": "hello"}, {"id": "2", "text": "whirl"}, {"id": "3", "text": "whoa"}], "id": "33"}]}}}

console.log(transform(data))

在这种情况下,Ramda版本对我来说更容易阅读,但只有很小的差异。

答案 3 :(得分:0)

由于副本包含一个数组,因此需要指定您要遍历该数组的位置。然后您有了正确的想法,然后更改值。

  

step.copy.map(s => ({text: s.text}))

  

需要成为

data['foo']['bar']['step'][0]['copy'].map(s => ({text: s.text}))

data.foo.bar.step[0].copy

data.foo.bar.step.map(v => {
    return v.copy.map(v => {
        return { text: v.text}
    })
});
  

示例

const data = {
  "foo": {
    "bar": {
      "id": "1",
      "step": [{
        "id": "33",
        "copy": [{
            "id": "1",
            "text": "hello",
          },
          {
            "id": "2",
            "text": "whirl",
          },
          {
            "id": "3",
            "text": "whoa",
          }
        ],
      }]
    }

  }
}
// Output: [{"text": "hello"}, {"text": "whirl"}, {"text": "whoa"}]
let sorted = data['foo']['bar']['step'][0]['copy'].map(s => ({text: s.text}))
// let sorted = data.foo.bar.step[0].copy.map(s => ({text: s.text}))
console.log(sorted);

然后您可以管道

pipe(sorted) 

答案 4 :(得分:-2)

获得一个或多个数组的原因是因为step值可以迭代。删除数组的2层意味着您仅限制了step数组的单个值:

pipe(
  path(['foo', 'bar', 'step', '0', 'copy']),
  map(s => ({text: s.text}))
) (data)

您要将所有step值合并到单个外部数组。

flatten(pipe(
  path(['foo', 'bar', 'step']),
  map(step => 
    step.copy.map(s => ({text: s.text}))
  ),
) (data))